gpt4 book ai didi

c++ - 将类型为 `int` 的临时对象转换为引用安全吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:03:42 26 4
gpt4 key购买 nike

在下面的程序中:

int Func()
{
int a = { 10 };
return a;
}
int main()
{
int& r = (int&)(const int&)Func();
r = 5;
}

r 是对类型 int 的临时引用。但是临时对象会立即被销毁,除非它们通常被分配给一个引用。上面的分配似乎不正常。在标准 C++ 中使用 r 安全吗?

最佳答案

简介: C 风格的转换等同于 (C++17 [expr.cast]):

int& r = const_cast<int&>( static_cast<const int&>(Func()) );

在子表达式 static_cast<const int&>(Func()) 中该行为由 C++17 [expr.static.cast]/4 描述(其中 T 是要转换为的类型):

If T is a reference type, the effect is the same as performing the declaration and initialization T t(e); for some invented temporary variable t (11.6) and then using the temporary variable as the result of the conversion

在这种情况下 Tconst int& , 所以引用的初始化类似于 const int& t(Func()); .

现在这段代码中有两个问题:

  • 临时的类型
  • 所涉及的临时工的生命周期

临时的类型是const int (C++17 [dcl.init.ref]/5.2.1.2)。因此,您的代码通过修改 const 对象导致未定义的行为。 Link to other SO question on this topic

对于此答案的其余部分(解决生命周期问题),我假设您更改了 r = 5一些只读为 r 的声明.


引用链接的行为随着 CWG 1299 的应用而改变.该缺陷于 2011 年 4 月提交,并于 2017 年 3 月解决。该解决方案未出现在 C++17 (N4659) 中;它只出现在 C++17 之后的草稿中。

该决议的状态为 DRWP,我的理解是这意味着它追溯适用于 C++17 但不适用于 C++14(如果有人想确认或更正这一点,那就太好了)。


无论如何,在某些情况下,此解决方案可以延长引用链的生命周期。写法是(N4762 class.temporary/6):

[...] The temporary object to which the reference is bound or the temporary object that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference if the glvalue to which the reference is bound was obtained through one of the following:

  • [...]
  • a const_cast, static_cast, dynamic_cast, or reinterpret_cast converting, without a user-defined conversion, a glvalue operand that is one of these expressions to a glvalue that refers to the object designated by the operand, or to its complete object or a subobject thereof,

在 CWG1299 之前,本段仅适用于从纯右值初始化引用,但现在如果指定对象是临时对象,它可以适用于从任何表达式类别初始化引用的情况。

请注意,临时物化在 C++17 中的工作方式是,当物化发生时,纯右值被转换为一个缺值,而这个缺值就是上面粗体文本所指的泛左值。

现在甚至有一个例子可以证实这一点:

const int& b = static_cast<const int&>(0); // temporary int has same lifetime as b

另一个已删除的答案中显示的编译器行为必须应用 CWG1299 的决议。

关于c++ - 将类型为 `int` 的临时对象转换为引用安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54736807/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com