Every class has its name injected into it as a member. So you can name A::Foo::Foo
. This is called the injected class name.
[class]
2 A class-name is inserted into the scope in which it is declared
immediately after the class-name is seen. The class-name is also
inserted into the scope of the class itself; this is known as the
injected-class-name. For purposes of access checking, the
injected-class-name is treated as if it were a public member name.[basic.lookup]
3 The injected-class-name of a class is also considered to be a
member of that class for the purposes of name hiding and lookup.
Because unqualified name lookup of the argument type begins in the scope of the class Bar
, it will continue into the scope of its base class to account for any member there. And it will find A::Foo::Foo
as a type name.
If you want to use the global type name, simply qualify it by its surrounding (global) namespace.
Bar(::Foo foo) {
c = foo.b;
}
Which is doing fully qualified lookup in a scope where the injected class name doesn’t appear.
For a followup “why” question see
- Why is there an injected class name?