c++ - C++14 中 std::initializer_list 对象的预期生命周期是多少?
问题描述
请考虑这个简化的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 << ". ";
}
https://gcc.godbolt.org/z/1GWvGfxne
GCC在这里打印
A() . ~A()
这意味着std::initializer_list
在范围结束时被破坏。
铿锵印:
A() ~A() .
在它被建造的那条线上摧毁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()};
...在两个编译器上产生相同的输出。
同时,为 C++17 编译时,您的原始代码在 GCC 和 Clang 上的行为相同。
推荐阅读
- powerpoint - 如何使用带有 VBA/JQuery/css/JavaScript/Node.js.js 的 MS Power Point 2007 为任何给定的 power point 演示文稿创建翻书动画效果
- mocha.js - 如何使用 chai 和 mocha 测试数组中的元素?
- powershell - 试图找到一个部门中的所有用户,并比较他们的 AD 组
- java - @Scheduled 处理需要很长时间时的行为。并行运行?
- javascript - 删除谷歌图表上 hAxis 之间的空白
- c++ - QtLocation Map 中有 3-D 映射吗?
- session - 如何在 gcp 应用引擎标准实例之间共享会话
- pycharm - 将 PyCharm 与包含多个项目的 monorepo 一起使用
- r - 带有插入符号(分类和回归训练)包的 data.table
- java - XSLT 选择节点而不丢失属性