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? TudoFoo
s 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 osFoo
s, portanto sou explícito sobre o que quero.
Se for necessário apenas usar os colchetes {} com apenas um dosFoo
s 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 combar
construtor de tomar trêsFoo0
s como argumentos. A mesma história aqui. Mas o erro não diz nada sobre declaração conflitante, mas sobre redefinição dex
.