Der folgende Code kompiliert nicht, es sei denn, die Kommentarzeile unkommentiert ist:C++ Operator-Komma/Vorwärts-Referenzcode kompiliert nicht
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>();
}
Am Komma-Operator, denkt der Compiler, die es braucht A<int>
zu abgeschlossen sein, auch wenn der Code nur in A<T>*
übergibt. Ich verstehe nicht warum. Es schlägt sowohl mit clang als auch mit g ++ fehl. Clang sagt
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.
ich jetzt im Debugger sitze den Compiler Debuggen :-) Ich denke, was passiert ist, dass der Compiler Argument abhängige Lookup verwendet zu finden passende operator,
s und die dazugehörigen Klassen und Namespaces für einen Zeiger auf eine Klasse enthalten die Klasse selbst, daher möchte der Compiler, dass die Klasse vollständig ist. Könnte sein.
so, was Ihre Frage? –
Warum kompiliert es nicht? Warum sollte der Compiler 'A' vollständig sein, wenn er 'Operator betrachtet, (B :: V, A *)'? Warum funktioniert es, wenn die kommentierte Zeile unkommentiert ist? –
Was hat der Fehler vom Compiler sagen? –