Il seguente codice non viene compilato, a meno che la linea commentata sia commentata:C++ operatore virgola non compila
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>();
}
verso l'operatore virgola, il compilatore pensa che ha bisogno di A<int>
essere completo, anche se il codice tratta solo tra A<T>*
. Non capisco perché. Fallisce con clang e g ++. Clang dice
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.
Ora sto seduto nel debugger il debug del compilatore :-) Penso che quello che sta accadendo è che il compilatore sta usando lookup argomento-dipendente per trovare corrispondenza operator,
s e le classi associate e Gli spazi dei nomi per un puntatore a una classe includono la classe stessa, quindi il compilatore desidera che la classe sia completa. Può essere.
quindi qual è la tua domanda? –
Perché non viene compilato? Perché il compilatore desidera che 'A' sia completo quando si guarda l'operatore '(B :: V, A *)'? Perché funziona quando la riga commentata non è commentata? –
cosa ha detto l'errore emesso dal compilatore? –