我是否正确地说const_cast后面的ref-to-const绑定到临时修改是好的?

Lig*_*ica 19 c++ const reference const-cast temporary-objects

我想检查一下我对此事的理解和结论.


在IRC上,有人问:

绑定到临时对象const_castconst引用是否可以接受?

翻译:他有一个临时的ref-to-const,他想抛弃它const来修改它.

我的回答是我之前曾问过一个类似的问题,其中的共识似乎是临时性本身并不是天生的const,因此你可以抛弃const你对它们的引用的性质,并通过结果修改它们.而且,只要原始参考const仍然存在,这不会影响临时的生命周期.

那是:

int main()
{
   const int& x = int(3);

   int& y = const_cast<int&>(x);
   y = 4;

   cout << x;
}
// Output: 4
// ^ Legal and safe
Run Code Online (Sandbox Code Playgroud)

我对吗?


(当然,这些代码是否真的是可取的完全是另一回事!)

Jam*_*nze 9

没有.

首先,据我所知,它是否是文字是无关紧要的.非类型的Rvalues总是具有非cv限定类型(§3.10/ 9),但是,在§8.5.3(引用的初始化)中,我们有:

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

[...]

-

否则,使用非参考拷贝初始化的规则(8.5)从初始化表达式创建并初始化类型为"cv1 T1"的临时类型.然后将引用绑定到临时.如果T1与T2有参考关系,则cv1必须与cv2相同,或者cv2更高,cv2必须与cv2相同; 否则,该计划是不正确的.

(以上所有要点都涉及左值或类型.)

在我们的例子中,我们有:

int const& x = ...;
Run Code Online (Sandbox Code Playgroud)

所以cv1 T1int const,我们创建的临时对象有类型 int const.这是一个顶级const(在对象上),因此任何修改它的尝试都是未定义的行为.

至少,这是我的解释.我希望标准对此有点清楚.

  • @ TomalakGeret'kal不是真的.§3.10/ 9讨论了左值和左值.像`3`或`int(3)`这样的表达式是一个rvalue.§8.5.3讨论了如何初始化引用; 引用永远不是rvalues,必须引用一个对象.所以§8.5.3说编译器创建一个临时对象,用rvalue初始化,并绑定对它的引用.你没有得到整数文字的引用,因为这样的东西不存在; 您将获得对其他不可见的未命名对象的引用,该对象具有引用的类型(而不是初始化程序的类型). (2认同)