除非注释行被取消注释,否则以下代码无法编译:
template <class T> struct R { static T& r(); };
struct M {
static char m(M&);
template <class T> static int m(const T&);
};
template <class T> struct A;
template <class T>
struct B {
struct U { };
struct V { M& operator,(U); };
enum { v = sizeof(M::m((R<V>::r(), R<A<T>*>::r()))) };
};
template <class T> struct A { B<T> y; };
int main()
{
// A<int>(); // Works if uncommented.
B<int>();
}
Run Code Online (Sandbox Code Playgroud)
在逗号运算符中,编译器认为它需要A<int>完成,即使代码只是在流量中A<T>*.我不明白为什么.它与clang和g ++都失败了.克朗说
h.cpp:13:36: error: field has incomplete type 'B<int>'
template <class T> struct A { B<T> y; };
^
h.cpp:11:38: note: in instantiation of template class 'A<int>' requested here
enum { v = sizeof(M::m((R<V>::r(), R<A<T>*>::r()))) };
^
h.cpp:17:5: note: in instantiation of template class 'B<int>' requested here
B<int>();
^
h.cpp:8:8: note: definition of 'B<int>' is not complete until the closing '}'
struct B {
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
我现在正坐在调试器中调试编译器:-)我认为正在发生的事情是编译器使用依赖于参数的查找来查找匹配的operator,s,并且指向类的指针的关联类和命名空间包括类本身,所以编译器希望该类完成.也许.
如果将 main 更改为以下内容,您会收到相同的错误消息:
int main()
{
// A<int>(); // Works if uncommented.
auto& x = R<A<int>*>::r();
B<int>();
}
Run Code Online (Sandbox Code Playgroud)
我要冒昧地说,正如你所暗示的那样。提及指向 an 的指针A<int>不会导致 的模板扩展A<int>。
这是有道理的(对我来说),因为它与提到指向前向声明类型的指针相同 - 您不需要此时完全定义的类型。
也许比我更聪明的人可以在标准中找到强制执行此操作的段落。