`const&&`绑定到所有prvalues(和xvalues)?

时间:2014-07-24 20:12:31

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

C ++标准定义了以下删除的功能;

template <class T>
void ref(const T&&) = delete;

template <class T>
void cref(const T&&) = delete;

这是为了通过禁止函数绑定到临时值(rvalues)来帮助确保函数不被滥用。

  • const &&是否绑定到所有rvalues,特别是prvalues?
  • const &&绑定到所有“移动的对象”(xvalues;基本上是从std::move或类似的东西返回的内容)?

我可以说它应该,但我没有任何“证据”。

  • 或者相反,是否存在rvalue(prvalue或xvalue)不会绑定到const &&的情况?
    • 若然,怎么会这样?

注意:评论中的一些清晰度,这个问题严重受到经典右值,prvalue值类别的影响。

2 个答案:

答案 0 :(得分:4)

T const&&可以绑定到Tconst T类型的右值。

从8.5.3 [dcl.init.ref] 第5段:

  

5 - 引用类型&#34; cv1 T1&#34;由类型&#34; cv2 T2&#34;的表达式初始化如下:[...]
   - 否则,[...]参考应为右值参考。 [...]
   - 如果初始化表达式为
   - 是一个xvalue,类prvalue,数组prvalue或函数lvalue和&#34; cv1 T1&#34;参考兼容&#34; cv2 T2&#34; [...]   然后引用绑定到初始化表达式[...]

的值

如果初始化表达式是非类型的prvalue,则为参考绑定创建临时副本(同上)。

参考兼容性在8.5.3p4中定义;它需要相同或基类关系以及相同或更高的cv资格。

因此,对于绑定到T const&&的右值,其cv资格必须不大于const

答案 1 :(得分:3)

我想在这里添加一些支持答案的经验证据。

template <class T>
void ref(T&) {}

template <class T>
void ref(volatile T&) {}

template <class T>
void ref(volatile const T&) {}

template <class T>
void ref(const T&) {}

template <class T>
void ref(const T&&) = delete;

// xvalues
int&& ax();
const int&& bx();
volatile int&& cx();
volatile const int&& dx();

// prvalues
int ap();
const int bp();
volatile int cp();
volatile const int dp();

void test()
{
    ref(ax());
    ref(bx());
    ref(cx());
    ref(dx());

    ref(ap());
    ref(bp());
    ref(cp());
    ref(dp());
}

在这种情况下,对ref的所有调用都无法编译,包括具有cv限定变体的xvalues和prvalues; msvc,gcc and clang都无法使用适当的&#34进行编译;尝试引用已删除的函数&#34;错误。