【问题标题】:Where in the C++ Standard is it stated that a const rvalue reference doesn't bind to an lvalue?C++ 标准在哪里声明 const 右值引用不绑定到左值?
【发布时间】:2014-05-18 02:43:54
【问题描述】:

C++ 标准中的什么地方规定了 const 右值引用不绑定到左值?

例如下面的代码无法编译:

#include <iostream>

int i = 10;

int f(const int&& j) { return j; }
int main()
{
    std::cout << f(i) << '\n';
}

【问题讨论】:

  • 可能无处可去。我不认为标准列出了所有不与其他事物绑定的事物。这个列表会很大。
  • 代码不编译是不是很奇怪?为什么应该呢?
  • 不仅仅是const 右值,你根本不能将左值绑定到右值引用...

标签: c++ c++11 language-lawyer rvalue-reference


【解决方案1】:

在 [dcl.init.ref]/5 的最后一个项目符号中(引用 n3485):

如果T1 [初始化引用的类型] 与T2 [初始化表达式的类型] 引用相关并且引用是右值引用, 初始化表达式不应是左值。

在这种情况下,cv-qualification 是无关紧要的。


/5 的第一个(主)项目符号不适用,因为该引用不是左值引用:

如果引用是左值引用并且初始化表达式 [...]

第二个(主要)要点适用:

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

[强调我的]

第一个子要点不适用,因为初始化器不是 xvalue 或函数纯右值,并且没有类类型。

第二个子要点是无条件的“否则”,因此最后一个子要点适用。


如果初始化器与被引用类型(T1)引用相关,则示例编译:

#include <iostream>

double i = 10;

int f(const int&& j) { return j; }
int main()
{
    std::cout << f(i) << '\n';
}

Live example

【讨论】:

  • 我相信你的意思是要点:“否则,引用应该是对非易失性 const 类型的左值引用(即 cv1 应该是 const),或者引用应该是右值引用。”我试图跟随这颗子弹无济于事。我只是找不到 const rvalue ref 的情况。
  • @user1042389 没有具体提及,但被更一般的规则涵盖:对 const 类型的右值引用是右值引用,因此此项目符号适用,第二个子项目符号不允许绑定左值到与引用相关的右值引用。
  • 您说您引用的是 N3485,但我记得这是 C++11 后的版本。我引用的是 N3337。
  • 我正在使用 N3485,因为它包含更多针对 C++11 缺陷的建议解决方案,但还没有 C++1y 扩展。我知道的三大编译器(MSVC、clang++、g++)在它们的 C++11 模式中包含了其中一些建议的解决方案。
  • 但这是否意味着 C++11 没有涵盖这一点?很难相信这是事实。
【解决方案2】:

[C++11: 8.5.3/3] 列出了引用的初始化器是如何工作的;你要找的东西就在那里。不过,这里逐字引用太详尽了。

【讨论】:

    猜你喜欢
    • 2017-04-13
    • 2015-06-25
    • 2011-02-14
    • 2017-04-15
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    相关资源
    最近更新 更多