A construção da chamada de função temporária é interpretada como declaração

Ultimamente, encontrei um problema que de alguma forma (mas apenas de alguma forma) faz sentido para mim. Ele é baseado na interpretação da construção de um temporário como declaração do argumento do construtor único (!). Por favor, dê uma olhada no exemplo mínimo abaixo.

#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.
}

Eu já li expressões como:

Foo(a);

São interpretados (se houver um construtor padrão) como declaração de a. Isso faz sentido e é totalmente bom, já que você pode usar os colchetes {} para tornar a construção explícita. Mas o que eu não entendo é:

Por que existe um problema com a construção de bar0? TudoFoos não tem um construtor padrão. Portanto, não faz sentido interpretar algo comoFoo0(x) como declaração dex.

Por que a construção debar1 ebar2 trabalhos? É óbvio para mim que a construção debar4 funciona, desde que eu uso os colchetes {} para todos osFoos, portanto sou explícito sobre o que quero.

Se for necessário apenas usar os colchetes {} com apenas um dosFoos para resolver o problema ... por que a construção debar3 falhou?

Além disso, x é declarado antes de qualquer barra ser construída. Por que o compilador não se queixa disso?

A última pergunta está relacionada à minha última linha de código de exemplo. Longa história: O que o compilador acha que eu quero que ele faça e onde sinto falta da aparência de sombreamento?

PS: Se for do seu interesse - eu uso o gcc-4.9.2.
PPS: Tentei o mesmo combarconstrutor de tomar trêsFoo0s como argumentos. A mesma história aqui. Mas o erro não diz nada sobre declaração conflitante, mas sobre redefinição dex.

questionAnswers(2)

yourAnswerToTheQuestion