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

如何调用接收std::function可变参数的C++ run模板函数?

关于std::function参数的run模板函数调用问题

你编写的第一个run模板函数可以通过编译,但调用时需要注意参数类型和值类别要求,先看原代码:

#include <iostream>
#include <functional>
#include <utility>
#include <string>

template<class... Args>
void run(std::function<void(Args...)>&& f, Args&&... args) {
    f(std::forward<Args>(args)...);
}


void greet(std::string name, int times) {
    for(int i = 0; i < times; ++i) {
        std::cout << "Hello, " << name << "!\n";
    }
}

int main() {
    std::function<void(std::string, int)> func = greet;
    run<std::string, int>(greet, std::string("Bob"), 2);  // 无法运行
    run(func, std::string("Bob"), 2);  // 无法运行
    return 0;
}

原调用失败的原因

  1. 第一个调用run<std::string, int>(greet, ...):greet是普通函数指针,不是std::function<void(std::string, int)>类型,无法匹配第一个参数的右值引用的std::function类型要求。
  2. 第二个调用run(func, ...):func是左值对象,而第一个参数是std::function<void(Args...)>&&(这是确定类型的右值引用,不是模板参数的万能引用),左值不能直接绑定到非const的右值引用。

正确的调用方式

方式1:将左值std::function转为右值传入

利用std::move把已有的左值func转成右值,此时编译器可以自动推导模板参数:

run(std::move(func), std::string("Bob"), 2);

方式2:直接传入临时std::function对象(右值)

可以显式构造临时std::function作为参数,既可以显式指定模板参数,也可以让编译器推导:

// 显式指定模板参数
run<std::string, int>(std::function<void(std::string, int)>(greet), "Bob", 2);

// 编译器自动推导Args
run(std::function<void(std::string, int)>(greet), std::string("Bob"), 2);

对比通用版本的run函数

你提到的通用版本:

template<class Functor, typename... Args>
void run(Functor&& f, Args&&... args) {
    f(std::forward<Args>(args)...);
}

这里的Functor&&是万能引用(模板参数的右值引用),可以接受左值、右值、函数指针、lambda等各种可调用对象,类型推导更灵活,因此调用时不需要额外处理值类别或类型转换,适用性更广。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:22:44