Konstruktion des temporären Funktionsaufrufs wird als Deklaration interpretiert

In letzter Zeit bin ich auf ein Problem gestoßen, das mir irgendwie (aber nur irgendwie) Sinn macht. Es basiert auf der Interpretation der Konstruktion einer temporären Variable als Deklaration des einzelnen (!) Konstruktorarguments. Bitte sehen Sie sich das unten stehende minimale Beispiel an.

#include <iostream>

class Foo0{
public:
  Foo0(int a){};
  void doStuff() {std::cout<<"maap"<<std::endl;};
};

class Foo1{
public:
  Foo1(int a){};
  void doStuff() {std::cout<<"maap"<<std::endl;};
};

class Foo2{
public:
  Foo2(int a){};
  void doStuff() {std::cout<<"maap"<<std::endl;};
};

class Bar{
public:
  Bar(Foo0 foo0, Foo1 foo1, Foo2 foo2){};
};

int main () {
  int x = 1;

  Bar bar0(Foo0(x), Foo1(x), Foo2(x)); // Does not work: conflicting declaration ‘Foo1 x’ previous declaration as ‘Foo0 x’; conflicting declaration ‘Foo2 x’ previous declaration as ‘Foo0 x’
  Bar bar1(Foo0{x}, Foo1(x), Foo2(x)); // Works WTF
  Bar bar2(Foo0(x), Foo1{x}, Foo2(x)); // Works WTF
  Bar bar3(Foo0(x), Foo1(x), Foo2{x}); // Does not work: conflicting declaration ‘Foo1 x’ previous declaration as ‘Foo0 x’
  Bar bar4(Foo0{x}, Foo1{x}, Foo2{x}); // Works totally makes sens to me

  x.doStuff(); //Dose not work. This makes sens to me. But in the context its curious though.
}

Ich habe bereits gelesen, dass Ausdrücke wie:

Foo(a);

Werden (wenn es einen Standardkonstruktor gibt) als Deklaration von a interpretiert. Dies macht Sinn und ist völlig in Ordnung, da Sie einfach die {} -Klammern verwenden können, um die Konstruktion explizit zu machen. Aber was ich nicht verstehe ist:

Warum gibt es ein Problem mit der Konstruktion von bar0? AlleFoos haben keinen Standardkonstruktor. Es macht also keinen Sinn, so etwas wie @ zu interpretiereFoo0(x) als Deklaration vonx.

Warum macht der Aufbau vonbar1 undbar2 Arbeit? Mir ist klar, dass die Konstruktion vonbar4 funktioniert, da ich die {} -Klammern für alle temporärenFoos, also ich bin explizit darüber, was ich will.

Wenn es nur notwendig ist, die {} -Klammern mit nur einem der @ zu verwendFoos um das Problem zu lösen ... warum macht der Aufbau vonbar3 Scheitern

Außerdem wird x deklariert, bevor ein Balken erstellt wird. Warum beschwert sich der Compiler nicht darüber?

Die letzte Frage bezieht sich auf meine letzte Codezeile. Lange Rede kurzer Sinn: Was denkt der Compiler, dass ich von ihm möchte, und wo vermisse ich das Erscheinen von Shadowing?

PS: Wenn es von Interesse ist - benutze ich den gcc-4.9.2.
PPS: Ich habe das gleiche mit @ versucbar 's Konstruktor nimmt dreiFoo0s als Argumente. Gleiche Geschichte hier. Aber der Fehler sagt nichts über widersprüchliche Deklaration aus, sondern über die Neudefinition vonx.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage