Порядок оценки элементов в списке-инициализации
вдругая тема@Dietmar дал это решение:
template <typename... T>
std::tuple<T...> parse(std::istream& in)
{
return std::tuple<T...>{ T(in)... };
}
основываясь на этом,
Использование инициализации скобки работает, потому чтопорядок оценки аргументов в списке инициализатора фигурной скобкиэто порядок, в котором они появляются, (подчеркните мой)
Соответствующий текст из стандарта C ++ (n3485):
В пределах списка инициализатора списка фигурных скобок предложения инициализатора, включая любые, которые являются результатом расширений пакета (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
, Даже идеон даетэтот вывод.
Это ошибка в компиляторе?