Nel other topic, @Dietmar ha dato questa soluzione:ordine di valutazione degli elementi nella lista-inizializzazione
template <typename... T>
std::tuple<T...> parse(std::istream& in)
{
return std::tuple<T...>{ T(in)... };
}
affermando che,
L'uso di inizializzazione del tutore funziona perché il ordine di valutazione degli argomenti in un elenco di inizializzazione delle parentesi graffe è l'ordine in cui appaiono. (Sottolineare la mia)
Il testo pertinente dal ++ standard C (n3485) è,
All'interno di inizializzazione-list di a-init-list rinforzato, l'inizializzatore-clausole, comprese quelle che risultano dalle espansioni del pacchetto (14.5.3), vengono valutate nell'ordine in cui appaiono. Cioè, ogni calcolo del valore ed effetto collaterale associato ad una data clausola di inizializzazione viene sequenziato prima di ogni calcolo del valore ed effetto collaterale associato a qualsiasi clausola inizializzatore che la segue nell'elenco separato da virgole della lista inizializzatore. [Nota: questo ordine di valutazione è valido indipendentemente dalla semantica dell'inizializzazione; ad esempio, si applica quando gli elementi dell'elenco inizializzatore vengono interpretati come argomenti di una chiamata del costruttore, anche se normalmente non vi sono vincoli di sequenziamento sugli argomenti di una chiamata. -end nota]
così ho provato a testare questo con il seguente codice:
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);
}
uscita prevista:
A1::data = A1
A2::data = A2
uscita effettiva:
A1::data = A2
A2::data = A1
Ho fatto qualcosa di sbagliato nel mio codice di test? Ho cambiato il mio codice a questo:
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
Stesso risultato di prima. Ho testato il mio codice con MinGW (GCC) 4.7.0
e 4.7.2
. Anche ideone dà this output.
È un errore nel compilatore?
clang-3.2 genera l'output previsto. Forse è un bug gcc? –
Questo è un bug GCC. Clang lo fa corretto. – Xeo
Cosa ci aspetti da noi? "Sì, è un bug a causa della citazione che stai dando". Non è stato detto due volte oggi?Sia nella domanda di @Dietmar che nella domanda i riferimenti di Dietmar sono stati forniti citazioni ed esempi che affermano che l'ordine è da sinistra a destra. –