成员函数通过模板中的成员函数指针调用shared_ptr

Mee*_*ons 24 c++ templates pointers smart-pointers c++11

这是一个模板函数,它接受一个指针(或类似指针的对象)和一个成员函数:

template <typename Ptr, typename MemberFunctor>
int example(Ptr ptr, MemberFunctor func )
{
    return (ptr->*func)();
}
Run Code Online (Sandbox Code Playgroud)

如果与普通指针一起使用时有效:

struct C
{
    int getId() const { return 1; }
};

C* c = new C;
example(c, &C::getId);    // Works fine
Run Code Online (Sandbox Code Playgroud)

但它不适用于智能指针:

std::shared_ptr<C> c2(new C);
example(c2, &C::getId);
Run Code Online (Sandbox Code Playgroud)

错误信息:

error: C2296: '->*' : illegal, left operand has type 'std::shared_ptr<C>'
Run Code Online (Sandbox Code Playgroud)

为什么?以及如何制作适合两者的东西?

son*_*yao 23

std::shared_ptr不支持指向成员的访问操作符(即->*.*).所以我们不能直接调用成员函数指针->*.您可以更改调用语法使用operator*operator.*,这同时适用于原始指针和智能指针.

template <typename Ptr, typename MemberFunctor>
int example(Ptr ptr, MemberFunctor func )
{
    return ((*ptr).*func)();
}
Run Code Online (Sandbox Code Playgroud)

生活


Tar*_*ama 12

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)();
}
Run Code Online (Sandbox Code Playgroud)

但是,我建议只是example参考T并调用func它.example不需要知道指针是如何存储的,所以它不应该要求所有这些额外的重载.

template <typename T, typename MemberFunctor>
int example(T&& t, MemberFunctor func )
{
    return (std::forward<T>(t).*func)();
}
Run Code Online (Sandbox Code Playgroud)

现在,如果你有std::shared_ptr<T>,你会打电话给example:

example(*my_shared_ptr, my_func); 
Run Code Online (Sandbox Code Playgroud)


Jar*_*d42 7

std::shared_ptr没有超载operator ->*.您可以添加一个重载:

template <typename Ptr, typename MemberFunctor>
int example(std::shared_ptr<Ptr> ptr, MemberFunctor func )
{
    return (ptr.get()->*func)();
}
Run Code Online (Sandbox Code Playgroud)