在这个其他主题中,@Dietmar给出了以下解决方案:
我在测试代码中做错了什么吗?我把我的代码改成了这样:
template <typename... T>
std::tuple<T...> parse(std::istream& in)
{
return std::tuple<T...>{ T(in)... };
}
声明如下:
使用花括号初始化的原因是,在花括号初始化列表中的参数求值顺序与它们出现的顺序相同。(强调我的)
C++标准(n3485)中相关的文本为:
在大括号初始化列表中,包括任何由pack扩展(14.5.3)导致的初始化程序子句在内的初始化程序列表将按照它们出现的顺序进行评估。也就是说,与给定初始化器子句相关联的每个值计算和副作用都在逗号分隔的初始化列表中后续的任何初始化器子句相关联的每个值计算和副作用之前排序。[注:这种评估顺序不受初始化语义的影响;例如,当将初始化列表的元素解释为构造函数调用的参数时,即使通常对于调用的参数不存在排序约束,它也适用。—结尾注]
所以我尝试使用以下代码进行测试:
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也给出了这个输出结果。
这是编译器的一个bug吗?