Fed*_*dor 33 c++ initialization object-lifetime temporary-objects c++20
我的一个朋友给我看了一个 C++20 程序:
#include <iostream>
struct A
{
A() {std::cout << "A()\n";}
~A() {std::cout << "~A()\n";}
};
struct B
{
const A &a;
};
int main()
{
B x({});
std::cout << "---\n";
B y{{}};
std::cout << "---\n";
B z{A{}};
std::cout << "---\n";
}
Run Code Online (Sandbox Code Playgroud)
在 GCC 中,它打印:
A()
~A()
---
A()
---
A()
---
~A()
~A()
Run Code Online (Sandbox Code Playgroud)
https://gcc.godbolt.org/z/ce3M3dPeo
因此,A在 y 和 z 情况下,的寿命会延长。
在 Visual Studio 中,结果是不同的:
A()
~A()
---
A()
---
A()
~A()
---
~A()
Run Code Online (Sandbox Code Playgroud)
所以A只有在 y 的情况下,的寿命才会延长。
你能解释一下为什么大括号的类型会影响对象的生命周期吗?
son*_*yao 28
gcc 是正确的。只有在聚合初始化中使用列表初始化语法(即使用大括号)时,临时对象的生命周期才会延长。
(C++20 起)使用直接初始化语法(括号)而不是列表初始化语法(大括号)初始化的聚合的引用元素中的引用的临时绑定一直存在,直到包含初始化器的完整表达式结束.
Run Code Online (Sandbox Code Playgroud)struct A { int&& r; }; A a1{7}; // OK, lifetime is extended A a2(7); // well-formed, but dangling reference
对于直接初始化:
(强调我的)
否则,如果目标类型是(可能是 cv 限定的)聚合类,则按照聚合初始化中的描述对其进行初始化,除了允许缩小转换、不允许指定的初始值设定项、指向引用的临时绑定不会延长其生命周期,没有大括号省略,任何没有初始化器的元素都是值初始化的。(C++20 起)
| 归档时间: |
|
| 查看次数: |
1115 次 |
| 最近记录: |