C++20中如何传递需作为模板类型成员函数的函数?
可以在C++20中实现你的需求
根据你的场景,有两种主流实现方式,分别对应“指定现有成员函数”和“传入自定义lambda/可调用对象”的需求:
方案一:传入成员函数指针作为模板参数
如果你只是想灵活指定要调用T类的某个已有成员函数,可以把成员函数指针作为Manager的额外模板参数,语法上最接近你想要的type.FUNC()形式:
#include <iostream> class Ex1 { public: int timestamp = 42; int get_timestamp() { return timestamp; } int get_double_timestamp() { return timestamp * 2; } }; // 新增auto类型的模板参数Func,用于接收成员函数指针 template<typename T, auto Func> class Manager { public: void process_data(T& type) { // 用成员函数指针的语法调用,等价于你想要的type.FUNC()形式 int result = (type.*Func)(); std::cout << "处理结果:" << result << std::endl; } }; int main() { Ex1 ex; // 实例化时指定要调用的成员函数 Manager<Ex1, &Ex1::get_timestamp> manager1; manager1.process_data(ex); // 输出:处理结果:42 Manager<Ex1, &Ex1::get_double_timestamp> manager2; manager2.process_data(ex); // 输出:处理结果:84 return 0; }
方案二:传入自定义可调用对象(包括lambda)
如果你需要传入自定义逻辑(比如lambda),可以借助C++20的std::invocable概念约束可调用对象,统一处理成员函数指针、lambda、函数对象等,虽然不是严格的type.FUNC()语法,但能实现相同逻辑且灵活性更高:
#include <iostream> #include <concepts> #include <functional> class Ex1 { public: int timestamp = 42; }; // 用std::invocable约束Func必须能接收T&作为参数 template<typename T, typename Func> requires std::invocable<Func, T&> class Manager { private: Func func_; public: explicit Manager(Func func) : func_(std::move(func)) {} void process_data(T& type) { // 用std::invoke统一调用,适配各种可调用类型 auto result = std::invoke(func_, type); std::cout << "处理结果:" << result << std::endl; } }; int main() { Ex1 ex; // 传入lambda,模拟成员函数逻辑 Manager<Ex1, decltype([](Ex1& obj) { return obj.timestamp; })> manager1([](Ex1& obj) { return obj.timestamp; }); manager1.process_data(ex); // 输出:处理结果:42 // 传入带自定义逻辑的lambda Manager<Ex1, decltype([](Ex1& obj) { return obj.timestamp + 10; })> manager2([](Ex1& obj) { return obj.timestamp + 10; }); manager2.process_data(ex); // 输出:处理结果:52 // 也可以传入成员函数指针(兼容方案一的场景) Manager<Ex1, decltype(&Ex1::timestamp)> manager3(&Ex1::timestamp); // 成员变量指针也能被std::invoke处理 manager3.process_data(ex); // 输出:处理结果:42 return 0; }
注意点
C++是静态类型语言,无法在运行时为类T动态添加成员函数,所以不能让传入的lambda真正成为T的成员函数。但上述两种方案已经可以满足“灵活指定要调用的函数,且逻辑上等价于调用成员函数”的需求。
内容的提问来源于stack exchange,提问作者ATK
相关产品推荐
相关产品推荐

