最近我发现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,std::placeholders::_1);
- }
Q2:这个操作符是否正确实施?有没有任何“黄金”规则如何实现这样的运算符,可能是我重新发明了轮子或进入完全错误的方向,你觉得怎么样?有没有办法让一个单一的功能实现这个操作符,而不是像在std中的占位符一样多的功能
之后我得出结论,std :: bind可以在我的invoke方法中使用.
- template <typename Pointer,typename... Args>
- auto invoke2(Pointer p,Args... args)
- -> decltype(std::bind(f,p,args...)())
- {
- return std::bind(f,args...)();
- }
以这种方式,我的示例也可以无需添加运算符 – > *到shared_ptr.
Q3:所以,std :: bind现在被认为是替换为operator-> *?