We know that a 'using declaration' for a namespace's member name in a scope where another entity is defined there with the same name, causes a compile time error: "symbol x is already defined".
The error is detected at the point the 'using declaration' appears not at use point like a 'using directive'.
A using declaration in a class scope allows only exposing a base class member name.
Here is an example:
#include <iostream>
using namespace std;
struct Foo{
Foo(int x) : x_(x){}
int x_ = 0;
};
struct Bar{
Bar(int y) : y_(y){}
int y_ = 0;
};
struct FooBar : Foo, Bar{
using Foo::Foo; // inheriting Foo's ctors
using Bar::Bar; // inheriting Bar's ctors
int x_ = 10;
// using Foo::x_; // error detected here
};
int main(){
FooBar fb(5); // error detected here
}
As you can see above the using declaration for Foo::x_ causes a compile-time error at the point the using appears and it is OK.
But the using declaration for base classes Foo and Bar constructors don't issue an error until the usage in main?!!
- Normally FooBar inherits Foo(int); so when
using Bar::Bar;
appears normally the compiler complains but the code works fine until I try to use that constructor.FooBar(int)
.
After inheriting all the constructors, the compiler defines a derived class ctor and make it call its base class one passing in its parameters to it so it is as if we wrote:
struct FooBar : Foo, Bar{
FooBar(int x) : Foo(x){}
FooBar(int x) : Bar(x){}
//...
};
So why the compiler allows such bug? and wait until the use of that ctor to flag ambiguity??
- It looks to me that a using declaration in such case undergoes the same thing like a using directive.