如何将成员函数指针类型传递给C++模板?
问题:如何正确传递成员函数类型给Invoker模板?
我尝试使用嵌套的std::invoke来委托方法调用,示例代码如下:
class Executor { public: bool Execute(bool someFlag); }; template <class TMemberFunction, class TInstance, typename TResponse> class Invoker { public: TResponse Invoke(TMemberFunction* function, TInstance* instance, bool someFlag) { return std::invoke(function, instance, someFlag); } }; void Main() { // Create an executor Executor executor; bool someFlag = true; // How can I pass the member function type here? Invoker<???, Executor, bool> invoker; // Invoke member method bool response = invoker.Invoke(&Executor::Execute, &executor, someFlag); }
请问将成员函数类型传递给Invoker模板的正确方式是什么?
编辑说明:已修正示例代码。
解决方法
1. 手动指定成员函数类型
Executor::Execute作为成员函数,它的类型是bool (Executor::*)(bool),直接将该类型作为第一个模板参数传入即可:
void Main() { Executor executor; bool someFlag = true; // 手动指定成员函数类型 Invoker<bool (Executor::*)(bool), Executor, bool> invoker; bool response = invoker.Invoke(&Executor::Execute, &executor, someFlag); }
2. 优化:让模板自动推导(更简洁)
手动指定成员函数类型繁琐且易出错,推荐通过以下方式让编译器自动推导类型:
方案一:将Invoke改为成员模板函数
把Invoker的Invoke方法改为模板函数,无需在实例化Invoker时指定任何模板参数:
class Invoker { public: template <class TMemberFunction, class TInstance> auto Invoke(TMemberFunction* function, TInstance* instance, bool someFlag) { return std::invoke(function, instance, someFlag); } }; void Main() { Executor executor; bool someFlag = true; Invoker invoker; // 无需指定模板参数 bool response = invoker.Invoke(&Executor::Execute, &executor, someFlag); }
这里用auto推导返回值,也可以显式指定返回值类型,auto的写法更灵活通用。
方案二:利用C++17类模板参数推导
如果使用C++17及以上版本,可保留原类模板结构,通过推导指引让编译器自动推导参数:
template <class TMemberFunction, class TInstance, typename TResponse> class Invoker { public: TResponse Invoke(TMemberFunction* function, TInstance* instance, bool someFlag) { return std::invoke(function, instance, someFlag); } }; // 添加模板推导指引(C++17及以上支持) template <class TMemberFunction, class TInstance, typename TResponse> Invoker(TMemberFunction*, TInstance*, TResponse) -> Invoker<TMemberFunction, TInstance, TResponse>; void Main() { Executor executor; bool someFlag = true; // 编译器自动推导所有模板参数 Invoker invoker{&Executor::Execute, &executor, bool{}}; bool response = invoker.Invoke(&Executor::Execute, &executor, someFlag); }
内容的提问来源于stack exchange,提问作者pathkon
相关产品推荐
相关产品推荐

