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

Lambda转std::function在Clang编译通过GCC报错,谁的处理合规?

GCC与Clang对Lambda转std::function<const int&()>的处理谁符合C++标准?

已知Lambda与std::function属于不同类型,无捕获Lambda可转换为函数指针,但以下代码在Clang中编译通过,却被GCC拒绝,MSVC则给出警告:

#include <functional>
#include <iostream>
#include <string>
int func() 
{ 
    return 5; 
}
int main()  
{
    
    std::function<const int&()> getter1 = 
                                        [] { return func(); }; //gcc rejects but clang accepts  
    getter1();
}

GCC报错信息

<source>: In function 'int main()':
<source>:12:41: error: conversion from 'main()::<lambda()>' to non-scalar type 'std::function<const int&()>' requested
   12 |                                         [] { return func(); }; //gcc rejects but clang accepts
      |                                         ^~~~~~~~~~~~~~~~~~~~~
Compiler returned: 1

MSVC警告信息

warning C4172: returning address of local variable or temporary
Compiler returned: 0

结论

Clang接受该代码的行为符合C++标准,GCC拒绝构造的行为属于实现层面的额外严格检查,但即使代码编译通过,调用getter1()会触发未定义行为。

详细解释

  1. std::function构造的标准要求
    std::function<R(Args...)>的模板构造函数要求传入的可调用对象F满足:调用f(Args...)的结果可以隐式转换为R。这里Lambda的返回类型是int(自动推导而来),而int临时对象可以合法绑定到const int&(C++标准允许临时对象绑定到const左值引用),因此构造std::function<const int&()>从该Lambda是符合标准的。

  2. GCC的额外检查
    GCC在这里做了超出标准的限制:它拒绝将返回右值的可调用对象绑定到返回引用的std::function,但这种限制并不是C++标准强制要求的。

  3. 调用时的未定义行为
    MSVC的警告点出了核心问题:当调用getter1()时,Lambda返回的临时int对象会被绑定到const int&返回,但这个临时对象的生命周期仅存在于getter1()的调用表达式内部,表达式执行完毕后临时对象立即销毁。此时如果保存或使用这个返回的引用,就会访问已经销毁的对象,触发未定义行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:42:13