C++ namespace collision in copy constructor

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?

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)