You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++如何将成员函数指针作为类模板的模板参数使用?

C++成员函数指针类模板实现方案

问题结论

需求完全明确,该功能在C++11及更高标准中均可实现,编译报错是语法使用错误导致的。

报错原因

你在类模板的第二个非类型参数(成员函数指针)前错误添加了template<typename... Args>前缀,该语法仅用于声明模板模板参数,不能用来描述带可变参数的成员函数指针,因此编译器解析语法失败抛出错误。

正确实现

C++11兼容实现

C++11标准下可以通过类模板偏特化匹配任意参数列表的void返回成员函数:

#include <vector>
#include <utility>

// 前置声明
template<typename T, typename FuncType, FuncType func>
class EngineSystem;

// 偏特化匹配返回void的T类成员函数
template<typename T, typename... Args, void(T::*func)(Args...)>
class EngineSystem<T, void(T::*)(Args...), func>
{
public:
    // 注册实例接口示例
    void addHandler(T* instance) {
        handlers_.push_back(instance);
    }

    template<typename... FwdArgs>
    void update(FwdArgs&&... args)
    {
        for (T* handler : handlers_)
        {
            (handler->*func)(std::forward<FwdArgs>(args)...);
        }
    }
private:
    std::vector<T*> handlers_;
};

用法示例

#include <string>

class TestClass {
public:
    void doSomething(int a, const std::string& b) {
        // 自定义业务逻辑
    }
};

// 实例化类模板
EngineSystem<TestClass, decltype(&TestClass::doSomething), &TestClass::doSomething> system;

// 使用流程:先注册实例,再调用update批量执行
TestClass ins1, ins2;
system.addHandler(&ins1);
system.addHandler(&ins2);
system.update(10, "test"); // 会同时调用ins1和ins2的doSomething方法

C++17及以上简化实现

C++17引入auto非类型模板参数和std::invoke,可以大幅简化代码,不需要偏特化:

#include <vector>
#include <utility>
#include <functional>
#include <type_traits>

template<typename T, auto func>
class EngineSystem
{
    // 编译期校验参数合法性,不需要校验可直接删除本段
    static_assert(std::is_member_function_pointer_v<decltype(func)>, "第二个模板参数必须是成员函数指针");
    static_assert(std::is_void_v<typename std::function<std::remove_pointer_t<decltype(func)>>::result_type>, "传入的成员函数返回值必须为void");
public:
    void addHandler(T* instance) {
        handlers_.push_back(instance);
    }

    template<typename... FwdArgs>
    void update(FwdArgs&&... args)
    {
        for (T* handler : handlers_)
        {
            std::invoke(func, handler, std::forward<FwdArgs>(args)...);
        }
    }
private:
    std::vector<T*> handlers_;
};

用法示例

// 不需要额外传函数类型,写法更简洁
EngineSystem<TestClass, &TestClass::doSomething> system;

内容的提问来源于stack exchange,提问作者JensB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 13:57:03