Порядок оценки элементов в списке-инициализации

в другая тема, @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, Даже идеон дает этот вывод.

Это ошибка в компиляторе?

21

Решение

Отвечая на мой собственный вопрос. Удаление вопроса не будет хорошей идеей, поскольку у кого-то может возникнуть такой же вопрос в будущем.

Да. Это ошибка в компиляторе GCC.

взято из комментария @Johannes Schaub к вопросу.

10

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]