Ответ 1
Вы можете перегрузить ->*
с помощью бесплатной функции. Он не должен быть членом.
template <typename P,
typename T,
typename M>
M& operator->* (P smartptr, M T::*ptrmem)
{
return (*smartptr).*ptrmem;
}
Теперь все, что имеет унарные operator*
, определенные (итераторы, интеллектуальные указатели, любые), также может использовать ->*
. Возможно, вы захотите сделать это немного более контролируемым образом, то есть определить его для известных итераторов, известных интеллектуальных указателей и т.д. Отдельно.
Это не будет работать для функций-членов по понятным причинам. Нужно специализироваться/перегружать для этого случая и вместо этого возвращать std::function
:
template <typename P,
typename T,
typename M,
typename ... Arg>
std::function<M(Arg&&...)>
operator->* (P smartptr, M (T::*ptrmem)(Arg... args))
{
return [smartptr,ptrmem](Arg&&... args) -> M
{ return ((*smartptr).*ptrmem)(std::forward<Arg>(args)...); };
}