I have the code:
#include <iostream>
class Foo {
};
namespace Bar {
struct Foo {
};
}
namespace Baz
{
void baz(const Foo &)
{
std::cout << "Hello";
}
}
int main()
{
Baz::baz(Bar::Foo());
}
Compiler can't figure out which Foo
want to use and produces the error:
main.cpp: In function 'int main()':
main.cpp:23:19: error: invalid initialization of reference of type 'const Foo&' from expression of type 'Bar::Foo'
23 | Baz::baz(Bar::Foo());
| ^~~~~
main.cpp:15:14: note: in passing argument 1 of 'void Baz::baz(const Foo&)'
15 | void baz(const Foo &)
|
Of course the simplest solution is to use either ::Foo
or ::Baz::Foo
, but I want to fix all possible ambiguities with O(1) lines of code.
My first idea was using namespace Bar
inside Baz
namespace:
namespace Baz
{
using namespace Baz;
//...
using-declaration: makes the symbol name from the namespace ns_name accessible for unqualified lookup as if declared in the same class scope, block scope, or namespace as where this using-declaration appears.
I expected that all Bar
names become part of Baz
namespace, and unqualified lookup prefers Baz::Foo
. But for some reason it doesn't work
But using Bar::Foo;
, in turn, does the trick. And that confuses me even more
namespace Baz
{
using Bar::Foo;
So, my question is: What is the difference between using namespace Bar
and using Bar::Foo
in this case?
cppreference is your friend.
As regards using namespace ns_name;
it reads
using-directive: From the point of view of unqualified name lookup of any name after a using-directive and until the end of the scope in which it appears, every name from ns_name is visible as if it were declared in the nearest enclosing namespace which contains both the using-directive and ns_name.
As regards using ns_name::name;
it reads
using-declaration: makes the symbol name from the namespace ns_name accessible for unqualified lookup as if declared in the same class scope, block scope, or namespace as where this using-declaration appears.
It seems complicated, but it isn't. Furthermore, learning things explained this way (which is close to standardese, I'd say) pays off when it comes to diving into the depths of C++.