c++ - 如何获得成员函数指针的类?

标签 c++ c++11

考虑代码:

class Character
{
  void kill();
  void send_to_wall();
}

template <typename T>
void GeorgeFunc(T fp)
{
  ??? obj;
  (obj.*fp)();
}

int main()
{
  GeorgeFunc(&Character::kill);
}

所以我的问题是:我怎样才能得到 ????在模板实例化期间,编译器似乎肯定知道这个类型是什么(Character),但我不确定如何获得它。我目前的解决方法是更改​​为:void GeorgeFunc(void (T::*fp)()),但是从成员函数指针中简单地获取类型会更清晰。 decltype(fp) 将返回 void(Character::*)(),而 decltype(fp()) 将返回 void 。有什么方法可以获取Character

最佳答案

是的,只是用一个特征来确定这个。

template <typename> struct member_function_traits;

template <typename Return, typename Object, typename... Args>
struct member_function_traits<Return (Object::*)(Args...)>
{
    typedef Return return_type;
    typedef Object instance_type;
    typedef Object & instance_reference;

    // Can mess with Args... if you need to, for example:
    static constexpr size_t argument_count = sizeof...(Args);
};

// If you intend to support const member functions you need another specialization.
template <typename Return, typename Object, typename... Args>
struct member_function_traits<Return (Object::*)(Args...) const>
{
    typedef Return return_type;
    typedef Object instance_type;
    typedef Object const & instance_reference;

    // Can mess with Args... if you need to, for example:
    static constexpr size_t argument_count = sizeof...(Args);
};

现在你的声明是:

typename member_function_traits<T>::instance_type obj;

但是,我会争辩说,因为您需要一个成员函数指针(其他类型将由于 (obj.*fp)()1 行而无法实例化) 你的函数应该直接采用成员函数指针而不是完全通用的类型。

所以这个定义不仅有效,而且我认为它更可取——当有人使用指向成员函数的指针以外的东西时,错误消息会更加清晰,因为参数类型将不兼容:

template <typename Return, typename Object>
void GeorgeFunc(Return (Object::*fp)())
{
    Object obj;
    (obj.*fp)();
}

请注意,这确实允许传递返回任何类型的指向成员函数的指针。因为我们并不真正使用返回值,所以我们不关心它是什么。没有理由像您的“变通办法”那样强制它为 void

使用此方法的唯一缺点是,如果您还打算接受指向声明为 const 的成员函数的指针,则需要两个重载。完全通用的实现没有这个限制。 (我一直希望指向 const 成员函数的指针可以隐式转换为指向非 const 成员函数的指针,但 C++ 目前不允许这样做。)


1 这并非 100% 正确。如果您像现在这样使用完全通用的类型,那么调用者理论上可以传递成员 data 指针而不是成员 function 指针。 obj.*fp 将评估为对数据成员的引用,然后您将对其调用 operator()()。只要数据成员的类型实现了该运算符,就可以实例化模板函数 GeorgeFunc

关于c++ - 如何获得成员函数指针的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28105077/

相关文章:

c++ - 从类中 move vector ,返回 && 或 move 到临时?

c++ - 使用 mingw 编译 websocketpp 示例代码时未定义对 `std::errc::operation_canceled` 的引用

c++ - 在循环中使用自动 C++

c++ - 字符串与整数的连接

c++ - 将 double 值保存到文件的可移植方法是什么?

c++ - 使用 qtcreator 在 qt 小部件中插入滚动条

c++ - MFC DYNAMIC_DOWNCAST 与 dynamic_cast

c++11 - 安置在D

C++,根据用户确认不断向文件添加记录

C++ 固定大小数组与同一类型的多个对象