考虑这个代码示例:
#include <initializer_list> #include <iostream> int main() { for(auto e: []()->std::initializer_list<int>{return{1,2,3};}()) std::cout<<e<<std::endl; return 0; }
我试图用g(gcc版本4.9.2(Debian 4.9.2-10))编译它)
输出正确.
在clang(Debian clang版本3.5.0-9(标签/ RELEASE_350 / final)(基于LLVM 3.5.0))输出例如:
0 2125673120 32546
其中第一行始终为0,最后两行为“随机”.
这是cl ang还是别的东西?我认为这个代码示例是正确的.
更新:
解决方法
5 An object of type
std::initializer_list<E>
is constructed from an initializer list as if the implementation allocated an array ofN
elements of typeE
,whereN
is the number of elements in the initializer list. Each element of that array is copy-initialized with the corresponding element of the initializer list,and thestd::initializer_list<E>
object is constructed to refer to that array. If a narrowing conversion is required to initialize any of the elements,the program is ill-formed.6 The lifetime of the array is the same as that of the
initializer_list
object.
您的lambda的return语句初始化一个临时std :: initializer_list< int>并返回其副本.这一切都很好,除了其引用的数组的生命期在完整表达式的结尾结束.通过lambda以外的initializer_list访问死亡数组会导致未定义的行为.
initializer_list不是容器,它是对临时容器的引用.如果你试图像一个容器一样使用它,你将会有一个糟糕的时间.
在C 14(引用N4140)第6段中澄清:
6 The array has the same lifetime as any other temporary object (12.2),except that initializing an
initializer_list
object from the array extends the lifetime of the array exactly like binding a reference to a temporary.
通过CWG issue 1290的解决方案.这个澄清使得不可能使用initializer_list作为例如C 11的意图的成员变量.然而,即使在C14中,您的程序也有未定义的行为.