关于shared_ptr和指向成员运算符` - >*`和`std :: bind`的指针

Pio*_*ycz 10 c++ operator-overloading boost-bind shared-ptr pointer-to-member

最近我发现shared_ptr没有指向成员运算符的指针->*.我创建了简单的例子:

template <typename Pointer, typename Function, typename... Args>
auto invoke1(Pointer p, Function f, Args... args) -> decltype((p->*f)(args...))
{
  return (p->*f)(args...);
}
struct A { 
    void g() { std::cout << "A::g()\n"; } 
};
int main() {
  A a;
  invoke1(&a, &A::g); // works!!
  std::shared_ptr<A> sa = std::make_shared<A>();
  invoke1(sa, &A::g); // compile error!!
}
Run Code Online (Sandbox Code Playgroud)

Q1:为什么会这样?为什么shared_ptr没有这个运算符?

我添加了这样的运算符,shared_ptr示例开始工作:

template <typename T, typename Result>
auto operator ->* (std::shared_ptr<T> pointer, Result (T::*function)()) ->decltype(std::bind(function, pointer))
{
    return std::bind(function, pointer);
}
template <typename T, typename Result, typename Arg1>
auto operator ->* (std::shared_ptr<T> pointer, Result (T::*function)(Arg1 arg1)) ->decltype(std::bind(function, pointer, std::placeholders::_1))
{
    return std::bind(function, pointer, std::placeholders::_1);
}
Run Code Online (Sandbox Code Playgroud)

Q2:这个运营商是否正确实施?是否有任何"黄金"规则如何实施这样的操作员,可能要么我重新发明轮子或进入完全错误的方向,你怎么看?有没有办法让一个函数实现这个运算符,而不是像std中的占位符一样多的函数...

之后我得出结论,std::bind可以在我的invoke方法中使用.

template <typename Pointer, typename Function, typename... Args>
auto invoke2(Pointer p, Function f, Args... args) 
                     -> decltype(std::bind(f, p, args...)())
{
   return std::bind(f, p, args...)();
}
Run Code Online (Sandbox Code Playgroud)

这样,我的例子也适用,而不需要添加operator ->*shared_ptr.

Q3:那么,std::bind现在被认为是替代operator->*

Ali*_*ice 6

在一个坚果shell中:是的std :: bind是成员函数指针的替代品.

为什么?因为成员函数指针很糟糕,它们唯一的目的是实现委托,这就是为什么std :: bind和std :: function做的

有关成员函数指针是如何实现的参考,看看我以前的答案在这里.简单来说,成员函数指针被标准削弱了,因为它们在强制转换后不允许调用; 这使得它们对于90%的人想要来自成员函数指针的行为毫无意义:委托.

出于这个原因,std :: function用于表示抽象的"可调用"类型,std :: bind用于将this绑定到成员函数指针.你绝对不应该使用成员函数指针,而是使用std :: bind和std :: function.