Mic*_*iak 10 c++ clang c++11 clang++
考虑这个代码示例:
#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;
}
Run Code Online (Sandbox Code Playgroud)
我尝试用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
Run Code Online (Sandbox Code Playgroud)
第一行总是0,最后两行是"随机".
这是clang或其他什么的错误?我认为这个代码示例是正确的.
更新:
当lambda函数返回类型是别的东西(例如std :: vector或std :: array)时,这段代码工作正常.
从 C++11 8.5.4 列表初始化 [dcl.init.list] 开始:
5 类型的对象
std::initializer_list<E>是从初始值设定项列表构造的,就好像实现分配了N类型 的元素数组E,其中N是初始值设定项列表中的元素数量。该数组的每个元素都使用初始值设定项列表的相应元素进行复制初始化,并且该std::initializer_list<E>对象被构造为引用该数组。如果需要缩小转换来初始化任何元素,则该程序格式错误。6 数组的生命周期与对象的生命周期相同
initializer_list。
returnlambda 语句初始化一个临时对象并std::initializer_list<int>返回其副本。这一切都很好,只是它引用的数组的生命周期在完整表达式的末尾结束。initializer_list通过lambda 外部访问失效数组会导致未定义的行为。
Aninitializer_list不是容器,它是对临时容器的引用。如果你尝试像容器一样使用它,你将会遇到麻烦。
在 C++14(引用 N4140)中,第 6 段被澄清为:
6 数组与任何其他临时对象 (12.2) 具有相同的生命周期,只不过
initializer_list从数组初始化对象会延长数组的生命周期,就像将引用绑定到临时对象一样。
根据CWG 第 1290 号决议。这一澄清使得不可能使用 as initializer_list,例如,成员变量,而这正是 C++11 的意图。然而,即使在 C++14 中,您的程序也有未定义的行为。
| 归档时间: |
|
| 查看次数: |
353 次 |
| 最近记录: |