通过模板中的成员函数指针调用 shared_ptr 的成员函数
Member function call on shared_ptr through member function pointer in template
这是一个模板函数,它接受一个指针(或类似对象的指针)和一个成员函数:
template <typename Ptr, typename MemberFunctor>
int example(Ptr ptr, MemberFunctor func )
{
return (ptr->*func)();
}
如果与普通指针一起使用时有效:
struct C
{
int getId() const { return 1; }
};
C* c = new C;
example(c, &C::getId); // Works fine
但它不适用于智能指针:
std::shared_ptr<C> c2(new C);
example(c2, &C::getId);
错误信息:
error: C2296: '->*' : illegal, left operand has type 'std::shared_ptr<C>'
为什么?以及如何制作同时适用于两者的东西?
std::shared_ptr
doesn't support pointer-to-member access operator(即 ->*
和 .*
)。所以我们不能直接调用带有->*
的成员函数指针。您可以更改调用语法以使用 operator*
和 operator.*
,这适用于原始指针和智能指针。
template <typename Ptr, typename MemberFunctor>
int example(Ptr ptr, MemberFunctor func )
{
return ((*ptr).*func)();
}
std::shared_ptr
不会超载 operator ->*
。您可以添加重载:
template <typename Ptr, typename MemberFunctor>
int example(std::shared_ptr<Ptr> ptr, MemberFunctor func )
{
return (ptr.get()->*func)();
}
std::shared_ptr
没有 operator->*
。您有两个主要选择:
您可以编写一个重载,它需要一个 std::shared_ptr
(也许一个用于 std::unique_ptr
):
template <typename T, typename MemberFunctor>
int example(std::shared_ptr<T> ptr, MemberFunctor func )
{
return ((ptr.get())->*func)();
}
但是,我建议只让 example
引用 T
并在其上调用 func
。 example
不需要知道指针的存储方式,因此不需要所有这些额外的重载。
template <typename T, typename MemberFunctor>
int example(T&& t, MemberFunctor func )
{
return (std::forward<T>(t).*func)();
}
现在,如果你有 std::shared_ptr<T>
,你会像这样调用 example
:
example(*my_shared_ptr, my_func);
这是一个模板函数,它接受一个指针(或类似对象的指针)和一个成员函数:
template <typename Ptr, typename MemberFunctor>
int example(Ptr ptr, MemberFunctor func )
{
return (ptr->*func)();
}
如果与普通指针一起使用时有效:
struct C
{
int getId() const { return 1; }
};
C* c = new C;
example(c, &C::getId); // Works fine
但它不适用于智能指针:
std::shared_ptr<C> c2(new C);
example(c2, &C::getId);
错误信息:
error: C2296: '->*' : illegal, left operand has type 'std::shared_ptr<C>'
为什么?以及如何制作同时适用于两者的东西?
std::shared_ptr
doesn't support pointer-to-member access operator(即 ->*
和 .*
)。所以我们不能直接调用带有->*
的成员函数指针。您可以更改调用语法以使用 operator*
和 operator.*
,这适用于原始指针和智能指针。
template <typename Ptr, typename MemberFunctor>
int example(Ptr ptr, MemberFunctor func )
{
return ((*ptr).*func)();
}
std::shared_ptr
不会超载 operator ->*
。您可以添加重载:
template <typename Ptr, typename MemberFunctor>
int example(std::shared_ptr<Ptr> ptr, MemberFunctor func )
{
return (ptr.get()->*func)();
}
std::shared_ptr
没有 operator->*
。您有两个主要选择:
您可以编写一个重载,它需要一个 std::shared_ptr
(也许一个用于 std::unique_ptr
):
template <typename T, typename MemberFunctor>
int example(std::shared_ptr<T> ptr, MemberFunctor func )
{
return ((ptr.get())->*func)();
}
但是,我建议只让 example
引用 T
并在其上调用 func
。 example
不需要知道指针的存储方式,因此不需要所有这些额外的重载。
template <typename T, typename MemberFunctor>
int example(T&& t, MemberFunctor func )
{
return (std::forward<T>(t).*func)();
}
现在,如果你有 std::shared_ptr<T>
,你会像这样调用 example
:
example(*my_shared_ptr, my_func);