最近我发现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::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
.
Q3:那么,std::bind
现在被认为是替代品operator->*
吗?