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()会触发未定义行为。
详细解释
std::function构造的标准要求
std::function<R(Args...)>的模板构造函数要求传入的可调用对象F满足:调用f(Args...)的结果可以隐式转换为R。这里Lambda的返回类型是int(自动推导而来),而int临时对象可以合法绑定到const int&(C++标准允许临时对象绑定到const左值引用),因此构造std::function<const int&()>从该Lambda是符合标准的。GCC的额外检查
GCC在这里做了超出标准的限制:它拒绝将返回右值的可调用对象绑定到返回引用的std::function,但这种限制并不是C++标准强制要求的。调用时的未定义行为
MSVC的警告点出了核心问题:当调用getter1()时,Lambda返回的临时int对象会被绑定到const int&返回,但这个临时对象的生命周期仅存在于getter1()的调用表达式内部,表达式执行完毕后临时对象立即销毁。此时如果保存或使用这个返回的引用,就会访问已经销毁的对象,触发未定义行为。
内容的提问来源于stack exchange,提问作者user20562802
相关产品推荐
相关产品推荐

