Fed*_*dor 8 c++ object-lifetime initializer-list language-lawyer c++14
请考虑这个简化的c++14程序:
#include <iostream>
struct A
{
A() { std::cout << "A() "; }
~A() { std::cout << "~A() "; }
};
int main()
{
auto l = std::initializer_list<A>{A()};
std::cout << ". ";
}
Run Code Online (Sandbox Code Playgroud)
https://gcc.godbolt.org/z/1GWvGfxne
GCC在这里打印
A() . ~A()
Run Code Online (Sandbox Code Playgroud)
意思std::initializer_list是在范围结束时被破坏。
叮当印:
A() ~A() .
Run Code Online (Sandbox Code Playgroud)
std::initializer_list在它建造的那条线上销毁。
两个编译器都在这里正确运行还是其中之一是错误的?
这是微妙的。
Astd::initializer_list由底层数组(由编译器生成)支持。这个数组就像一个临时对象,std::initializer_list是一种绑定到它的引用类型。因此,只要“引用”存在,它就会延长临时数组的生命周期。
在 C++14 中,我们不保证复制省略。所以应该发生的事情是好像std::initializer_list<A>{A()}产生了一个临时的initializer_list,将另一个临时数组绑定到它,并将临时数组复制initializer_list到l.
std::initializer_list就生命周期延长而言,其行为类似于常规引用。只有原始引用会延长生命周期,而我们的原始引用本身是临时的。因此,在包含 的初始化的完整表达式的末尾,底层数组不存在l。Clang 是正确的。
直接初始化...
std::initializer_list<A> l {A()};
Run Code Online (Sandbox Code Playgroud)
...在两个编译器上产生相同的输出。
同时,在为 C++17 编译时,您的原始代码在 GCC 和 Clang 上的行为相同。
| 归档时间: |
|
| 查看次数: |
124 次 |
| 最近记录: |