从更高范围返回左值的 Lambda 函数

Posted

技术标签:

【中文标题】从更高范围返回左值的 Lambda 函数【英文标题】:Lambda function returning lvalue from higher scope 【发布时间】:2020-04-13 13:25:51 【问题描述】:
int main() 
    int x;
    auto& getx = [&]() 
        return x;
    
    
    getx() = 1;

这似乎不可能,因为它给了我:

错误:无法将 'main()::&' 类型的非 const 左值引用绑定到 'main()::' 类型的右值| em>

为什么?以及如何做到这一点

【问题讨论】:

【参考方案1】:

lambda 表达式创建一个未知类类型的临时对象(称为闭包)。临时对象不能分配给非常量引用。这意味着你需要

auto&& getx = [&]() 
    return x;

这样你就可以得到一个对闭包的右值引用,或者

auto getx = [&]() 
    return x;

所以你只是得到了关闭。

这将使代码编译,但仍需要多一点才能使getx 的返回值成为对x 的引用。为此,您需要添加

auto getx = [&]() -> int& 
    return x;


// or

auto getx = [&]() -> auto& 
    return x;


// or

auto getx = [&]() -> decltype(auto) 
    return x;
;

另请注意,main 必须始终返回 int。您应该调高编译器警告级别,以便在您尝试使用 void main 时出错。

【讨论】:

感谢快速回复,但是,我要求的是一个左值,而这两个不是 @Sho 你想要getx 是什么?您希望它是对x 的引用,还是希望它返回对x 的引用,还是返回x 的值? 引用标题“从更高范围返回左值的 Lambda 函数”基本上让我很高兴getx() = 1; @Sho 好的,我已经更新了答案以包含该部分。 很好的答案,最后比另一个更好!另一个帮助我更快,但你解释得很好【参考方案2】:

您必须指定 lambda 返回对 int - int& 的引用,并通过 () 调用闭包:

auto& getx = [&]() -> int&  // -> int& added
    return x;
();                         // () added

临时值不能绑定到 lvalue 引用。如果您想让getx 成为对x 变量的引用,则必须从您的lambda 返回引用。

【讨论】:

也可以使用-> auto&不指定类型 真的非常感谢你,它与我的其余代码配合得非常好,让我了解了闭包?

以上是关于从更高范围返回左值的 Lambda 函数的主要内容,如果未能解决你的问题,请参考以下文章

C/C++返回值与左值

clojure 函数,左值和返回值

lambda 函数返回值的有效性

c++中为啥赋值运算符重载返回类型是引用

& 返回左值或右值是啥?

C|指针的10种经典应用场合