Search code examples
c++templatesargument-dependent-lookup

Undefined class template is not instantiated to check for friend functions


The following program compiles (see on godbolt), but it would not compile if we uncommented the definition of Buffer.

template <int size>
struct Buffer /*{ char buf[size]; }*/;

template <class T>
struct Wrapper { void operator+() {} };

Wrapper<Buffer<-5>> a;

void f() { +a; }

The reason, the uncommented version does not compile: +a triggers ADL, and to collect all candidates for operator+, all associated classes must be checked for friend functions. Buffer<-5> is an associated class, so it must be instantiated. Instantiation fails, hence the compilation error. See this question.

I wonder if Buffer<-5> must be instantiated, why don't we have a compilation error, if Buffer is not defined?


Solution

  • You can (implicitly) instantiate a class template from only a declaration; you get an incomplete class type, just like from struct A; ([temp.inst]/2). It’s not an error, of course, to do ADL with an incomplete associated class; the class in question is simply not searched for friend declarations.