初始化列表中元素的求值顺序
Order of evaluation of elements in list-initialization
在另一个话题中,@Dietmar给出了这样的解决方案:
template <typename... T>
std::tuple<T...> parse(std::istream& in)
{
return std::tuple<T...>{ T(in)... };
}
说,
使用大括号初始化是有效的,因为在大括号初始化列表中,参数的求值顺序与它们出现的顺序相同。(强调我)
c++标准(n3485)中的相关文本是,
在大括号初始化列表的初始化列表中,初始化子句,包括包展开(14.5.3)产生的任何初始化子句,按照它们出现的顺序求值。也就是说,在初始化器列表的逗号分隔列表中,与给定初始化器子句关联的每个值计算和副作用都排在与它后面的任何初始化器子句关联的每个值计算和副作用之前。[注:无论初始化的语义如何,这个求值顺序都保持不变;例如,当初始化器列表的元素被解释为构造函数调用的参数时,即使调用的参数通常没有排序约束,它也适用。-end note]
所以我试着用下面的代码来测试:
template<int N>
struct A
{
std::string data;
A(std::istream & stream) { stream >> data; }
friend std::ostream& operator<<(std::ostream & out, A<N> const & a)
{
return out << "A"<<N<<"::data = " << a.data;
}
};
typedef A<1> A1;
typedef A<2> A2;
template<typename ...Args>
void test(std::istream & stream)
{
std::tuple<Args...> args { Args(stream)... };
std::cout << std::get<0>(args) << std::endl;
std::cout << std::get<1>(args) << std::endl;
}
int main()
{
std::stringstream ss("A1 A2");
test<A1,A2>(ss);
}
预期输出:A1::data = A1
A2::data = A2
实际输出:A1::data = A2
A2::data = A1
我在测试代码中做错了什么吗?我把代码改成这样:
std::stringstream ss("A1 A2");
std::tuple<A1,A2> args{A1(ss), A2(ss)};
std::cout << std::get<0>(args) << std::endl;
std::cout << std::get<1>(args) << std::endl
与之前相同的输出。我用MinGW (GCC) 4.7.0
和4.7.2
测试了我的代码。甚至ideone也给出了这样的输出。
是编译器中的错误吗?
回答我自己的问题。删除这个问题不是一个好主意,因为将来有人可能会有同样的问题。
是的。这是GCC编译器中的一个错误。
- Bug 51253 - [c++ 11][DR 1030]在括号-init-list 中初始化子句的求值顺序(sequence -before关系)
摘自@Johannes Schaub对这个问题的评论
相关文章:
- 为什么用户定义的函数不按照给定的顺序对相同长度的元素进行排序?
- 快速排序 - 三个中位数枢轴选择 - 某些元素顺序不正确
- 序列容器 - 只能按顺序访问元素
- 如何检查 2 个 c++ 数组在 O(1) 或 O(log n) 时间复杂度中是否相同(所有元素都相同,顺序很重要)?
- 保留从一个多集复制到另一个多集的元素的顺序
- 如何在 C++ 中将从文本文件中读取的元素推送和弹出到数组中,并按 Revserse 顺序输出堆栈?
- 查找数组的第一个和最后一个索引,其中 from 和 to 元素的顺序总和最大
- 编写一个递归功能,该功能采用数组并以相反顺序显示元素,而无需在末尾启动数组的索引
- 编写链接函数的更短/更有效的方法,该函数按字典顺序添加新元素
- stable_sort不遵守元素的顺序
- 从容器中获取随机元素,该容器在恒定时间内没有严格的元素顺序
- 如何在默认和二维数组中找到顺序扩大元素的位置
- 多重映射是否保证广告顺序与其初始值设定项中给出的元素顺序匹配
- 调用std::nth_element后第n个元素之前的元素顺序
- 控制地图中元素的顺序
- 指针集中元素的顺序
- 一种按排序顺序保持元素的数据结构,支持快速插入和计算连续元素之间的最大差异
- 双向循环列表中的赋值运算符以错误的顺序添加元素
- 更改STL多集中两个相等元素的顺序
- 初始值设定项列表中元素的求值顺序