This post回答了我的原始问题:如何在成员函数上进行模板化?
答案具有代码:
struct Foo {
void Bar() { // do something
}
};
template <typename TOwner, void(TOwner::*func)()>
void Call(TOwner *p) {
(p->*func)();
}
int main() {
Foo a;
Call<Foo, &Foo::Bar>(&a);
return 0;
}
我正在尝试使用共享指针来完成同样的事情。我发现这不起作用:
template <typename TOwner, void(TOwner::*func)()>
void Call(std::shared_ptr<TOwner> p) {
(p->*func)();
}
但是,这可行
template <typename TOwner, void(TOwner::*func)()>
void Call(std::shared_ptr<TOwner> p) {
(p.get()->*func)();
}
是否有更好的方法来实现这一目标?
答案 0 :(得分:3)
让我尝试解决“是否有更好的方法来实现这一目标?”问题的一部分:如果可以使用C ++ 17,那么std::invoke
可以很好地处理指向成员函数和智能指针的指针:
#include <memory>
#include <functional>
auto a = std::make_shared<Foo>();
std::invoke(&Foo::Bar, a); // Ok: pass the shared_ptr itself
std::invoke(&Foo::Bar, *a); // Also ok: pass a reference to the pointee
std::invoke
在这种情况下可以替换Call
函数模板,但仍然接受任意成员函数指针。