繁体   English   中英

带有lambda表达式的rvalue和左值引用 - gcc与msvc

[英]rvalue and lvalue reference with lambda expressions - gcc vs. msvc

在C ++中,将rvalue隐式转换为左值引用是非法的。 考虑以下代码,其中左值引用绑定到右值(lambda):

int main()
{
    auto& f = []() -> void {};
    return 0;
}

gcc(4.8.1)不接受这样的代码(完全有道理)。 但是,Microsoft编译器确实接受它意味着要么接受非标准代码,要么C ++允许左值引用绑定到rvalue lambda表达式的特定情况。

问题:哪个假设是正确的?

你的问题的核心是: rvalues可以绑定到非const 左值引用吗?

标准说没有 rvalues只能绑定到const 左值引用。

我认为相关的标准段落是8.5.3 / 5

对类型“cv1 T1”的引用由类型“cv2 T2”的表达式初始化,如下所示:

...

  • 否则,引用应是对非易失性const类型的左值引用(即,cv1应为const),或者引用应为右值引用。

然而,微软有一个长期存在的“功能”,允许这种非标准的行为,这解释了你正在目睹的事情。

但是,Microsoft编译器确实接受它意味着要么接受非标准代码,要么C ++允许左值引用绑定到rvalue lambda表达式的特定情况。

MSVC以拥有这个(不那么好的)编译器扩展而闻名。 它只是允许绑定rvalues来引用非const引用:

A& x = A(); // Illegal in C++, allowed by MSVC

引用 Herb Sutter(ISO C ++标准委员会主席):

一个符合标准的C ++编译器总是允许其他非法的C ++代码编译并赋予它一些含义 - 嘿,它可以选择允许内联COBOL,如果一些怪异的编译器编写者愿意实现该扩展,可能是在一些太多的Tequilas之后。 对于某些类型的扩展,C ++标准要求编译器至少发出一些诊断来说明代码不是有效的ISO C ++,就像这个编译器那样。

他进一步解释了以下示例是如何违法的:

// Example 2

string f() { return "abc"; }

void g() {
string& s = f();       // illegal?
  cout << s << endl;
}

请访问Sutter的此链接以获取解释,以避免重复SO上的文章。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM