下面的程序编译(见 godbolt(,但如果我们取消注释Buffer
的定义,它将无法编译。
template <int size>
struct Buffer /*{ char buf[size]; }*/;
template <class T>
struct Wrapper { void operator+() {} };
Wrapper<Buffer<-5>> a;
void f() { +a; }
原因是,未注释的版本无法编译:+a
触发 ADL,并且要收集operator+
的所有候选者,必须检查所有相关类的friend
函数。Buffer<-5>
是一个关联的类,因此必须对其进行实例化。实例化失败,因此编译错误。看到这个问题。
我想知道Buffer<-5>
是否必须实例化,如果没有定义Buffer
,为什么我们没有编译错误?
您可以(隐式地(仅从声明中实例化类模板;您将获得不完整的类类型,就像来自struct A;
([temp.inst]/2(一样。 当然,使用不完整的关联类执行 ADL 并不是错误;所讨论的类根本不会搜索好友声明。