Im other topic gab @Dietmar diese Lösung:Auftrag der Auswertung der Elemente in Liste-Initialisierung
template <typename... T>
std::tuple<T...> parse(std::istream& in)
{
return std::tuple<T...>{ T(in)... };
}
dass die besagt,
Die Verwendung von Klammer Initialisierung funktioniert, weil die Reihenfolge der Auswertung der Argumente in einer Klammerinitialisierungsliste ist die Reihenfolge, in der sie erscheinen. (Betont Mine)
Der entsprechende Text aus dem C++ Standard (n3485) ist,
Innerhalb der Initialisierer-Liste einer verspannt-init-Liste, die Initialisierer-Klauseln auch etwaig, die zur Folge hat aus Pack-Expansionen (14.5.3) werden in der Reihenfolge ausgewertet, in der sie auftreten. Das heißt, jede Wertberechnung und jeder Nebeneffekt, der einer gegebenen Initialisierungsklausel zugeordnet ist, wird vor jeder Wertberechnung und jedem Nebeneffekt, der mit einer Initialisierungsklausel verknüpft ist, die ihr folgt, in der kommagetrennten Liste der Initialisierungsliste sequenziert. [Anmerkung: Diese Bewertungsordnung gilt unabhängig von der Semantik der Initialisierung; zum Beispiel gilt es, wenn die Elemente der Initialisiererliste als Argumente eines Konstruktoraufrufs interpretiert werden, obwohl normalerweise keine Sequenzbeschränkungen für die Argumente eines Aufrufs bestehen. -Ende note]
Also habe ich versucht, dies mit dem folgenden Code zu testen:
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);
}
Erwartete Ausgabe:
A1::data = A1
A2::data = A2
tatsächlicher Ausgang:
A1::data = A2
A2::data = A1
Habe ich in meinem Testcode etwas falsch gemacht? Ich habe meinen Code folgendermaßen geändert:
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
Gleicher Ausgang wie zuvor. Ich habe meinen Code mit MinGW (GCC) 4.7.0
und 4.7.2
getestet. Selbst Ideon gibt this output.
Ist es ein Fehler im Compiler?
clang-3.2 generiert die erwartete Ausgabe. Vielleicht ist es ein GCC-Bug? –
Dies ist ein GCC-Fehler. Clang bekommt es richtig. – Xeo
Was erwarten Sie von uns? "Ja, es ist ein Fehler wegen des Zitats, das du gibst". Ist das heute nicht zweimal gesagt worden?Sowohl in der Frage von @Dietmar als auch in der Frage Dietmar wurden Hinweise, Zitate und Beispiele gegeben, die besagen, dass die Reihenfolge von links nach rechts ist. –