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

std::function是否兼容值传递与const引用传递的签名?

std::function兼容不同参数签名的问题解答

这是标准C++的合法特性吗?

这是标准C++规定的合法特性,并非GCC 11的编译器扩展。

std::function的设计本身就支持兼容参数类型的可调用对象:只要被存储的可调用对象能够接受std::function签名中定义的实参(即实参可以隐式转换为可调用对象的参数类型),就可以被构造到std::function中。

在你的代码场景里:

  • std::function的签名是void(S const&),调用时传入的临时对象S{}会被绑定到S const&类型的参数上;
  • 对于参数为S的lambda来说,S const&类型的实参可以通过隐式拷贝构造转换为S类型,满足lambda的参数要求,因此可以用来构造std::function。

调用端如何确定传引用还是拷贝?

调用端(函数f)不需要关心具体是传引用还是拷贝,它只需要严格按照std::function的签名void(S const&)传递参数——也就是传递一个绑定到临时对象S{}的S const&左值引用。

具体是引用还是拷贝,完全由被存储的可调用对象(lambda)的参数类型决定:

  • 当lambda参数是S const&时,直接引用传入的临时对象,不会发生拷贝;
  • 当lambda参数是S时,会将S const&引用的对象拷贝一份,作为lambda的参数使用——这个拷贝操作是在std::function的调用操作符执行时完成的,属于std::function对可调用对象的适配过程。

代码示例

定义部分:

struct S {
    int a{3};
};

using callback = std::function<void(S const&)>;

void f(callback&& cb) { cb(S{}); }

主函数部分:

int main()
{
    f([](S const& s) { std::cout << s.a << std::endl; });
    f([](S s) { s.a = 5; std::cout << s.a << std::endl; });
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:07:31