1

How come the following piece of code compiles (and prints V::operator+)?

#include <iostream>

namespace V {

struct B {};

template<typename T>
auto operator+(T rhs) -> T {
    std::cout << "V::operator+\n";
    return rhs;
}

}

struct A : V::B {};

int main() {
    +A();
}

The class A is outside of the namespace V and inherits from B, which is inside V. V also contains an operator template that could, for example, be used on B.

No operator+ is defined for A outside of V, and yet it can be called on A without any qualification (something like V::operator+(A())). Removing the inheritance produces the expected error 'operator+' not defined.

Why can this operator be used outside of V without qualification?

Nelfeal
  • 12,593
  • 1
  • 20
  • 39
  • It's called ADL. https://stackoverflow.com/questions/8111677/what-is-argument-dependent-lookup-aka-adl-or-koenig-lookup – Eljay Nov 02 '18 at 18:07

1 Answers1

2

Argument-dependent lookup extends to the namespaces of the base classes. [basic.lookup.argdep]/2.2:

If T is a class type (including unions), its associated classes are: the class itself; the class of which it is a member, if any; and its direct and indirect base classes. Its associated namespaces are the innermost enclosing namespaces of its associated classes.

Thus, when the compiler is looking for an operator+ to apply to type A, it also searches in the namespace V because A has a base class that is a member of V.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312