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

C++中如何传递带可变参数的函数指针作为参数?

问题解决:将带可变参数的函数作为参数传递给自定义函数foo()

需要实现自定义函数foo(),使其能接收一个带可变数量参数的函数指针,以及该函数所需的调用参数,最终调用目标函数并输出预期结果。当前代码运行报错:main.cpp:13:12: error: expected primary-expression before ‘...’ token,期望:

  • 调用foo(&bar, 10, 20, "Hello!")输出Test a: 10 Test b: 20 Test c: Hello!
  • 调用foo(&baz, 2, 2)输出4

错误代码示例

#include <iostream>

template<typename... Ts>
void foo(void (*func)(Ts...)){
    func(Ts...);
}

void bar(int a, int b, std::string c){
    std::cout << "Test a: " << a << " Test b: " << b << " Test c: " << c << "\n";
}

void baz(int x, int y){
    std::cout << x+y << "\n";
}

int main()
{
    foo(&bar, 10, 20, "Hello!"); // Expected: "Test a: 10 Test b: 20 Test c: Hello!"
    foo(&baz, 2, 2);             // Expected: "4"
    // main.cpp:13:12: error: expected primary-expression before ‘...’ token

    return 0;
}

错误原因分析

  1. 原foo()模板仅定义了接收函数指针的参数,未预留接收目标函数调用参数的位置,导致调用foo时参数数量不匹配
  2. func(Ts...)中的Ts...是模板参数的类型列表,并非实际要传递的数值,编译器无法将其识别为有效表达式,这是报错的直接原因

修正后的代码

#include <iostream>
#include <utility> // 用于std::forward实现完美转发

// 修改foo模板,同时接收函数指针和可变调用参数
template<typename Func, typename... Args>
void foo(Func func, Args&&... args){
    // 完美转发参数到目标函数,保留参数的左值/右值属性
    func(std::forward<Args>(args)...);
}

void bar(int a, int b, std::string c){
    std::cout << "Test a: " << a << " Test b: " << b << " Test c: " << c << "\n";
}

void baz(int x, int y){
    std::cout << x+y << "\n";
}

int main()
{
    foo(&bar, 10, 20, "Hello!"); // 字符串字面量会隐式转换为std::string
    foo(&baz, 2, 2);

    return 0;
}

关键改动说明

  • 调整foo()的模板参数:用Func接收任意函数指针类型,Args...接收目标函数所需的可变调用参数
  • 在foo()的参数列表中添加Args&&... args,用于接收实际传递的参数
  • 使用std::forward<Args>(args)...进行完美转发,避免不必要的参数拷贝,同时适配左值和右值参数
  • 字符串字面量可直接传入,会自动隐式转换为std::string类型

运行结果

编译运行后会输出:

Test a: 10 Test b: 20 Test c: Hello!
4

完全符合预期输出要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 11:56:45