Man*_*uel 6 c++ pointers reference rvalue-reference temporary-objects
如果我们想用不同的类型初始化引用,我们需要将其设置为 const (const type*),以便可以隐式生成临时对象并将引用绑定到 with。或者,我们可以使用右值引用并实现相同的[1]:
右值引用可用于延长临时对象的生命周期(注意,对 const 的左值引用也可以延长临时对象的生命周期,但不能通过它们进行修改):
[...]
样品
情况1
double x = 10;
int &ref = x; //compiler error (expected)
Run Code Online (Sandbox Code Playgroud)
案例2
double x = 10;
const int &ref = x; //ok
Run Code Online (Sandbox Code Playgroud)
案例3
double x = 10;
int &&ref = x; //ok
Run Code Online (Sandbox Code Playgroud)
如果我们尝试对 const 指针(const type* &)做同样的事情,并用非 const 指针(type*)初始化它,与我预期的不同,只有情况 2 有效。为什么情况3会导致编译器错误?为什么没有生成临时文件?
情况1
int x = 10;
int *pX = &x;
const int* &ref = pX; //compiler error (expected)
Run Code Online (Sandbox Code Playgroud)
案例2
int x = 10;
int *pX = &x;
const int* const &ref = pX; //ok (expected)
Run Code Online (Sandbox Code Playgroud)
案例3
int x = 10;
int *pX = &x;
const int* &&ref = pX; //compiler error (why?)
Run Code Online (Sandbox Code Playgroud)
在带有标志 -std=c++20 (和其他一些)的 gcc 12.1.0 和 clang 14.0.4 中,上面的情况 3 无法编译。
为什么在 int&、int&& 等情况下都运行良好,而在指针的情况下却出现编译器错误?我目前的知识是否存在一些不准确的地方?(我是新手)
如果我们对纯右值(int*)做同样的事情,一切都会很好
案例3
int x = 10;
//int *pX = &x;
const int* &&ref = &x; //ok (why?)
Run Code Online (Sandbox Code Playgroud)
相关问题:
参考
该标准有两种类型与参考相关的概念。这是通过两个相似的类型来实现的,这基本上意味着它们是否是具有相同数量的指针但可能不同的 cv 限定符的相同类型(例如,int和const int是相似的,int* const ** volatile并且volatile int** const *是相似的,并且至关重要的是int*和const int*是相似的)。
标准指出([dcl.init.ref]p(5.4.4)):
如果
T1与 参考相关T2:
- 如果引用是右值引用,则初始化表达式不应是左值。
由于const int* &&ref = pX;是右值引用,并且T1 = const int*与 引用相关T2 = decltype(pX) = int*,因此这适用,因此这是不允许的。const int* &&ref = std::move(pX);不会遇到这个问题,因为初始化器不再是左值。当然,显式进行 const 转换const int* &&ref = (const int*) pX;也是可行的。
据推测,这是不允许的const T x; T&& y = x;(绑定y到 的临时副本x),但由于标准的怪癖,它也扩展到了指针。