2010-01-16 5 views
2

Ma question est un peu liée à this un.fonction d'ami dans la définition de modèle

Je veux surcharger l'opérateur < < pour une classe et j'ai trouvé deux notations différentes que les deux de travail:

template <class T> 
class A{ 
    T t; 
public: 
    A(T init) : t(init){} 
    friend ostream& operator<< <> (ostream &os, const A<T> &a); //need forward declaration 
    //template <class U> friend ostream& operator<< (ostream &os, const A<U> &a); 
}; 

-je définir des choses identiques avec différentes notations? Ou est la première version plus restrictive dans quelle instance (dans ce cas seulement l'instance avec le même T que ma classe A) de < < est ami de A?

Répondre

1

La première version limite l'amitié au operator<< pour le type spécifique A<T>, tandis que le second fait une operator<< qui prend un A<SomeType> un ami.

Alors oui, la première est plus restrictive:

template<class T> 
ostream& operator<< (ostream& os, const A<T>& a) { 
    A<double> b(0.0); 
    b.t; // compile error with version 1, fine with version 2 
    return os; 
} 

int main() { 
    A<int> a(0); 
    cout << a << endl; 
} 
+0

Couple de choses. Premièrement, je pense que vous vouliez dire 'os << b.t' plutôt que 'os << b.i' pour sortir la variable membre possédée. Deuxièmement, l'exemple ci-dessus fonctionnerait bien avec l'opérateur << instance car il utiliserait la fonction 'ostreame & operator << (ostream & os, double num)', et non la version de modèle déclarée. – workmad3

+0

J'avais la tête ailleurs, semble-t-il, mais je l'ai réparée en attendant. –

0

Il se trouve que la définition des fonctions d'ami ont une exception pour les modèles. Il vous permet d'écrire ceci:

template <class T> 
class A{ 
    T t; 
public: 
    A(T init) : t(init){} 
    friend ostream& operator<<(ostream &os, const A &a) 
    { // Implementation in the class 
    } 
}; 

Et il a l'avantage de créer une fonction normale automatiquement créée pour chaque instance de A<T> vous créez.

Pour la référence: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.16

+0

avec "exception" vous voulez dire, que vous n'avez pas à écrire A dans la définition de l'opérateur? Ma question: est-ce vraiment un avantage? Ok, vous n'avez pas la version du template de <<, mais dans les cas ci-dessus, il y a aussi une instance du template pour << si elle est utilisée quelque part avec une classe spécifique. – haselhorstk

+0

Le principal avantage serait que vous n'avez pas besoin des déclarations anticipées ... vous devez toujours le définir dans chaque classe. –

+0

Le véritable avantage est que vous ne définissez aucun modèle de fonction! Donc, vous n'avez aucun des problèmes associés, comme avec la coercition. – PierreBdR

Questions connexes