看起来您在上面的示例中创建了两个初始化列表。临时{"hello", "stackoverflow"}
和std::initializer_list<std::string> a
。
在 gcc 上,{}
初始化列表实际上是临时数组,其生命周期在完整语句之后结束(除非std::initializer_list
在下面示例中的注释行中直接绑定到 like)。
第一个列表的内部数组的生命周期在a
' 构造函数返回后立即结束,因此a
' 数组现在指向无效内存(gcc 仅复制指针)。您可以检查,std::string
在您进入循环之前调用了析构函数。
当你进入循环时,你正在读取无效的内存。
根据最新的标准草案 (n3242),第 18.9/1 节,初始化列表甚至不能像那样复制(它们不提供带参数的构造函数)。
#include <initializer_list>
#include <iostream>
class A
{
public:
A(int)
{ }
~A()
{
std::cout << "dtor" << std::endl;
}
};
int main()
{
std::initializer_list<A> a({A(2), A(3)});
// vs std::initializer_list<A> a{A(2), A(3)};
std::cout << "after a's construction" << std::endl;
}
使用 gcc 4.5.0,我得到
dtor
dtor
after a's construction