“const&&;`是否绑定到所有prvalues(和xvalues)? C++标准定义了删除的下列函数;p> template <class T> void ref(const T&&) = delete; template <class T> void cref(const T&&) = delete; 模板 void ref(const T&&)=删除; 模板 void cref(const T&&)=删除;

“const&&;`是否绑定到所有prvalues(和xvalues)? C++标准定义了删除的下列函数;p> template <class T> void ref(const T&&) = delete; template <class T> void cref(const T&&) = delete; 模板 void ref(const T&&)=删除; 模板 void cref(const T&&)=删除;,c++,c++11,language-lawyer,rvalue-reference,rvalue,C++,C++11,Language Lawyer,Rvalue Reference,Rvalue,这有助于通过禁止函数绑定到临时值(右值)来确保函数不会被误用 const&是否绑定到所有右值,特别是PR值 const&&是否会绑定到所有“移动对象”(xvalue;基本上是从std::move或类似内容返回的内容) 我可以推断应该这样做,但我没有任何“证据” 或者相反,是否存在右值(prvalue或xvalue)不绑定到常量和&的情况? 如果是,如何 注意:从评论中可以看出,这个问题严重偏向于经典的右值,即prvalue类别 T const&可以绑定到T或const T类型的右值

这有助于通过禁止函数绑定到临时值(右值)来确保函数不会被误用

  • const&
    是否绑定到所有右值,特别是PR值
  • const&&
    是否会绑定到所有“移动对象”(xvalue;基本上是从
    std::move
    或类似内容返回的内容)
我可以推断应该这样做,但我没有任何“证据”

  • 或者相反,是否存在右值(prvalue或xvalue)不绑定到
    常量和&
    的情况?
    • 如果是,如何

注意:从评论中可以看出,这个问题严重偏向于经典的右值,即prvalue类别

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

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

5-对“cv1 T1”类型的引用由“cv2 T2”类型的表达式初始化,如下所示:[……]
-否则,[…]参考应为右值参考。[…]
-如果初始值设定项表达式
-是xvalue、类prvalue、数组prvalue或函数左值,且“cv1 T1”与“cv2 T2”的引用兼容[…] 然后将引用绑定到初始值设定项表达式[…]的值

如果初始值设定项表达式是非类类型的prvalue,则会为引用绑定创建临时副本(同上)

8.5.3p4中定义了参考兼容性;它需要相同或基本的关系以及相同或更高的简历资格


因此,对于要绑定到
T const&
的右值,其cv限定值必须不大于
const
,我想在这里添加一些实证证据来支持答案

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());
}
模板
void ref(T&){}
模板
void ref(volatile T&){}
模板
void ref(volatile const T&){}
模板
void ref(常数T&){}
模板
void ref(const T&&)=删除;
//xvalues
int&&ax();
常量int&&bx();
volatile int&&cx();
volatile const int&&dx();
//prvalues
int-ap();
常数int-bp();
易失性int-cp();
volatile const int dp();
无效测试()
{
ref(ax());
ref(bx());
ref(cx());
ref(dx());
ref(ap());
ref(bp());
ref(cp());
ref(dp());
}

在这种情况下,对
ref
的所有调用都无法编译,包括带有cv限定变量的xvalues和prvalues;msvc,编译失败,出现相应的“试图引用已删除的函数”错误。

你所说的“移动类型”是什么意思?@JosephMansfield,从
std::move
或类似程序返回的内容。请注意:一般来说,
const T&
在类型为
volatile T
的右值时无法工作。但是
T
是在这里推导出来的,因此如果需要,
T
可以被推断为
volatile
限定类型。@user2485710:“在理解
std::move
的功能时不会出错”当然,只要有人告诉你,
std::move
实际上不会移动任何东西。请注意,
std::move
总是返回一个右值,除非参数是函数类型的——在这种情况下,它返回一个左值,因为没有函数类型的右值。但是,“对函数的右值引用”仍将绑定到函数类型的左值。但正如hvd在问题注释中指出的,由于推导出了
T
,函数仍然可以采用
volatile
限定参数。
volatile
只是推导出的
T
的一部分。在过载分辨率中,pr值与xvalue被视为相同