È solo un avvertimento su un aspetto difficile della lingua. Quando si dichiara una funzione friend
, non è un membro della classe in cui si trova la dichiarazione. È possibile definirlo lì per comodità, ma in realtà appartiene allo spazio dei nomi.
Dichiarare una funzione amico che non è un modello, all'interno di un modello di classe, dichiara ancora una funzione non modello nello spazio dei nomi. Non è né un membro della classe, né esso stesso un modello. Tuttavia, è il generato dal modello di classe.
La generazione di funzioni non modello da un modello è un po 'confusa. Ad esempio, non è possibile aggiungere una dichiarazione per tale funzione al di fuori del blocco class
. Pertanto è necessario definirlo anche all'interno del blocco class
, il che ha senso perché il modello di classe lo genererà.
Un'altra cosa complicata per gli amici è che la dichiarazione all'interno di class Float {}
non dichiara la funzione nello spazio dei nomi. Lo si può trovare solo attraverso la risoluzione di overload del significato dipendente dall'argomento, ad esempio specificando che un argomento ha tipo Float
(o un riferimento o un puntatore). Questo non è un problema per operator+
, poiché è probabile che sia sovraccaricato in ogni caso e non verrà mai chiamato, tranne che per i tipi definiti dall'utente.
Per un esempio di potenziale problema, immagina di avere un costruttore di conversioni Float::Float(Bignum const&)
. Ma Bignum
non ha operator+
. (Spiacente, esempio forzato.) Si desidera fare affidamento su operator+(Float const&, Float const&)
per l'aggiunta Bignum
. Ora my_bignum + 3
non verrà compilato perché nessuno degli operandi è un Float
quindi non riesce a trovare la funzione friend
.
Probabilmente, non hai nulla di cui preoccuparti, purché la funzione in questione sia operator
.
Oppure, è possibile modificare lo friend
come modello. In tal caso, deve essere definito all'esterno del del blocco class {}
e dichiarato prima, invece di dover essere dichiarato e definito all'interno di.
template<int E, int F> // now this is a template!
Float<E, F> operator+ (const Float<E, F> &lhs, const Float<E, F> &rhs);
template<int E, int F>
class Float
{
// deduce arguments E and F - this names operator+< E, F >.
friend Float<E, F> operator+<> (const Float<E, F> &lhs, const Float<E, F> &rhs);
};
Si consiglia di leggere http://www.parashift.com/c++-faq-lite/templates.html#faq-35.16 – UncleBens