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

标签 c++ operator-overloading shared-ptr boost-bind 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!!
}

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);
}

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...)();
}

通过这种方式,我的示例也无需将 operator ->* 添加到 shared_ptr 即可运行。

问题 3:那么,std::bind 现在是否被视为 operator->* 的替代品?

最佳答案

简而言之:是的,std::bind 是成员函数指针的替代品。

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

关于如何实现成员函数指针的引用,请参阅我之前的回答 here .用最简单的话来说,成员函数指针被标准削弱了,因为它们不允许在转换后调用;这使得它们对于 90% 的人希望从成员函数指针获得的那种行为毫无意义:委托(delegate)。

因此,std::function 用于表示抽象的“可调用”类型,std::bind 用于将 this 绑定(bind)到成员函数指针。你绝对不应该乱用成员函数指针,而是使用 std::bind 和 std::function。

关于c++ - 关于 shared_ptr 和指向成员运算符 `->*` 和 `std::bind` 的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17696664/

相关文章:

C++ 运算符重载不起作用

c++ - 调用 get 后将 shared_ptr 分配给另一个

c++ - 为什么 C++ 模板编译器不能从协变智能指针参数推断类型?

c++ - 需要使用互斥量显式定义复制构造函数

C++ 字符串 cout 字符丢失

c++ - 将多种(不同)类型的参数传递给模板函数

c++ - 从字节数组创建IMFByteStream

c# - 我可以在小数类型上重载 + 运算符吗?

c++ - 在 ITK 中使用 DemonsRegistrationFilter 的困难

c++ - C++ 中的 std::variant cout