2013-04-13 14 views
5
template <typename T> 
class rp { 
}; 

template <template <typename> class P> 
struct b { 
    template <class, template <typename> class FriendP> 
    friend void f(b<FriendP> from); 
}; 

template <class, template <typename> class P> 
void f(b<P> from) { 
} 

int main() { 
    b<rp> v; 
    f<int>(v); 
    return 0; 
} 

Clang 3.3 (SVN) compila bene, mentre GCC 4.8 rifiuta:GCC rivendica una funzione amico per essere sovraccaricato, chiamata ambigua, clang compila

main.cpp: In function 'int main()': 
main.cpp:17:10: error: call of overloaded 'f(b<rp>&)' is ambiguous 
    f<int>(v); 
     ^
main.cpp:17:10: note: candidates are: 
main.cpp:12:6: note: void f(b<P>) [with <template-parameter-1-1> = int; P = rp] 
void f(b<P> from) { 
    ^
main.cpp:8:17: note: void f(b<FriendP>) [with <template-parameter-2-1> = int; FriendP = rp; P = rp] 
    friend void f(b<FriendP> from); 
       ^

Mi chiedo perché GCC sostiene f da sovraccarico . Quindi penso che sia un bug GCC.

Quale compilatore ha ragione?

+0

Quale 'f()' richiama clang? –

+0

Poiché solo la definizione 'f' outside' b' ha un corpo e non ci sono errori di linker, che 'f' deve essere invocato. In effetti c'è solo una 'f'. – hpohl

+0

Direi che si tratta di un bug GCC. –

risposta

1

L'iniezione di amici non esiste più nello standard C++, vedere this per informazioni a riguardo. Tuttavia, poiché la funzione friend dichiarata all'interno della struct b "agisce" su un parametro di tipo "b", la funzione viene trovata tramite ADL (ricerca dipendente dall'argomento). In questo caso vengono dichiarate 2 diverse funzioni con la stessa firma e il compilatore si lamenta.

questo è probabilmente quello che voleva dire:

template <template <typename> class P> 
struct b { 
    template <class, template <typename> class FriendP> 
    friend void f(b<FriendP> from){}; 
}; 

ma non usare questo nel codice vero e proprio come è, dal momento che i problemi "funzione duplicato" possono, come si vede, facilmente sorgere (uso corretto dei namespace può essere di aiuto con questo rispetto).

Il codice può essere testato here

Un buon riferimento per l'utilizzo (così come un buon esempio di vita reale del motivo per cui sono necessari) di funzioni friend template può essere trovato al punto 46 della c efficace ++

+0

Perché gcc pensa che la funzione amico abbia 3 parametri modello? –

+0

Perché in realtà ce ne sono 3: il primo è quello identificato dalla classe, il secondo è FriendP, il terzo è l'argomento del template di FriendP –

+0

Il problema non è la visibilità. Il problema è che entrambe le dichiarazioni di 'f' dovrebbero essere viste come dichiaranti lo stesso modello di funzione. – aschepler

Problemi correlati