Lately I ran into a problem which somehow (but only somehow) makes sense to me. It is based on interpreting the construction of a temporary as declaration of the single (!) constructor argument. Please have a look at the minimal example below.
#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.
}
I already read that expressions like:
Foo(a);
Are interpreted (if there is a standard constructor) as declaration of a. This makes sense and it is totally fine, since you can just use the {}-brackets to make the construction explicit. But what I do not understand is:
Why is there a problem with the construction of bar0? All
Foos do not have a standard constructor. So it does not make sense to interpret something likeFoo0(x)as declaration ofx.Why does the construction of
bar1andbar2work? It is obvious to me that the construction ofbar4works, since I use the {}-brackets for all temporaryFoos, thus I am explicit about what I want.If it is only necessary to use the {}-brackets with only one of the
Foos to solve the problem... why does the construction ofbar3fail?Furthermore, x is declared before any Bar is constructed. Why does the compiler not complain about that?
The last question is related to my last line of example code. Long story short: What does the compiler think that I want him to do and where do I miss the appearance of shadowing?
PS: If it is of interest -- I use the gcc-4.9.2.
PPS: I tried the same with bar's constructor taking three Foo0s as arguments. Same story here. But the error says nothing about conflicting declaration but about redefinition of x.