如何在C++中向函数传递函数名与可变参数列表?
在C++中实现Python式的函数传参调用功能
在Python里可以轻松把函数和参数传给外部函数,由外部函数负责调用目标函数并传入参数。在C++中,我们可以通过多种方式实现类似功能,以下是几种常用方案:
一、基础模板可变参数实现(最通用,无额外依赖)
利用C++的模板可变参数特性,直接接收任意可调用对象和参数,完美转发后调用:
#include <iostream> template<typename Func, typename... Args> void perform(Func fun, Args&&... args) { // 完美转发参数,避免不必要的拷贝 fun(std::forward<Args>(args)...); } // 测试用的目标函数 void action1() { std::cout << "执行action1\n"; } void action2(int p) { std::cout << "执行action2,参数:" << p << "\n"; } void action3(int p, const std::string& r) { std::cout << "执行action3,参数:" << p << ", " << r << "\n"; } int main() { perform(action1); perform(action2, 10); perform(action3, 20, "hello"); return 0; }
这个方案支持普通函数、lambda表达式、仿函数等所有可调用对象,且通过完美转发保证参数传递的效率。
二、结合std::function的实现(适合统一接口场景)
如果需要统一可调用对象的类型(比如存储到容器中延迟调用),可以用std::function配合参数绑定:
#include <iostream> #include <functional> void perform(const std::function<void()>& fun) { fun(); } int main() { // 直接传递无参函数 perform(action1); // 用std::bind绑定参数,生成无参的可调用对象 perform(std::bind(action2, 10)); perform(std::bind(action3, 20, "hello")); // 用lambda表达式更灵活,适合自定义调用逻辑 perform([](){ action2(15); }); perform([](){ action3(25, "world"); }); return 0; }
这种方式把带参数的调用转换成无参的可调用对象,适合需要统一接口的场景。
三、使用std::invoke(C++17+,支持更多调用场景)
如果你的项目基于C++17及以上,std::invoke可以统一处理各种调用场景,包括类成员函数、成员变量等:
#include <iostream> #include <functional> template<typename Func, typename... Args> void perform(Func fun, Args&&... args) { std::invoke(fun, std::forward<Args>(args)...); } // 测试类成员函数 class MyClass { public: void print(int num) { std::cout << "成员函数调用,参数:" << num << "\n"; } }; int main() { perform(action1); perform(action2, 10); MyClass obj; // 调用类成员函数,需要传递对象指针/引用 perform(&MyClass::print, &obj, 30); return 0; }
std::invoke的优势在于它能处理所有合法的可调用操作,让代码的通用性更强。
内容的提问来源于stack exchange,提问作者Gabriel Staples
相关产品推荐
相关产品推荐

