如何用C++可变参数模板实现最后参数为lambda的函数?
C++ 用可变参数模板实现类似JS的回调函数模式
当然可以,C++的可变参数模板完全能实现这种“任意数量前置参数 + 最后一个lambda回调”的函数模式,下面是具体的实现示例:
完整代码示例
#include <iostream> #include <tuple> #include <vector> #include <string> #include <utility> // 模拟业务处理函数compute,可根据实际需求自定义逻辑 template<typename... Args> auto compute(Args&&... args) { // 这里示例将所有参数打包为tuple返回,实际可替换为任意业务逻辑 return std::make_tuple(std::forward<Args>(args)...); } // 核心函数:接收任意前置参数,最后一个参数为回调 template<typename... Params, typename Callback> void doSomething(Params&&... params, Callback&& callback) { // 确保至少有一个前置参数(和JS示例的判断逻辑对应) static_assert(sizeof...(Params) >= 1, "doSomething requires at least one parameter plus the callback"); // 调用compute处理前置参数 auto result = compute(std::forward<Params>(params)...); // 调用回调传递结果 std::forward<Callback>(callback)(std::move(result)); } int main() { // 调用示例,写法和JS版本高度相似 doSomething(1, std::vector<int>{1,2,3}, true, std::string("123"), [](auto&& result) { // 打印回调接收的结果(这里是tuple类型) std::apply([](auto&&... args) { ((std::cout << args << " "), ...); std::cout << "\n"; }, std::forward<decltype(result)>(result)); }); return 0; }
关键要点说明
- 参数包匹配:通过
template<typename... Params, typename Callback>,C++模板推导会自动将最后一个可调用对象(比如lambda)匹配到Callback类型,前面的所有参数匹配到Params...参数包。 - 完美转发:使用
std::forward保持参数的原始值类别(左值/右值),避免不必要的拷贝开销。 - 灵活性:回调可以是lambda、函数指针、仿函数等任何可调用对象,且通过
auto参数可以适配compute返回的任意类型。 - 参数校验:通过
static_assert实现编译期参数数量校验,替代JS中的运行时判断。
内容的提问来源于stack exchange,提问作者Stephen.W
相关产品推荐
相关产品推荐

