6
votes

Opérateur << (Ostream & OS, ...) pour la classe de modèles

Pourquoi je ne peux pas utiliser le même paramètre de modèle pour une fonction d'ami qui prend un argument de modèle? Je veux dire que le code ci-dessous est OK!

template <class Vertex>
class Edge
{
   friend ostream& operator<<(ostream& os, const Edge<Vertex>& e);
   /// ...
};

template <class T>
ostream& operator<<(ostream& os, const Edge<T>& e)
{
   return os << e.getVertex1() << " -> " << e.getVertex2();
}


1 commentaires

Un ami est un modèle, l'autre n'est pas.


4 Réponses :


2
votes
 friend ostream& operator<<(ostream& os, const Edge<Vertex>& e);

0 commentaires

3
votes

Vous pouvez utiliser après xxx

qui fait opérateur << ami vers bord

Dans votre deuxième cas, vous faites un opérateur de non-modèle d'ami, mais la définition de cet opérateur est un modèle, vous avez donc une référence non définie, mais cette affaire peut être utilisée si vous souhaitez que votre opérateur <<< / code> pour le béton bord ( bord par exemple).


1 commentaires

Cela nécessitera une déclaration d'avenir du modèle de fonction <<<< / code> (qui nécessitera à son tour une déclaration avant du modèle de classe Edge ).



2
votes

Le problème est qu'ici: xxx pré>

vous déclarez une fonction non-modèle (qui sera différent pour chaque instanciation de bord code>) pour être un ami code>, et pas l'instanciation du modèle. p>

la solution la plus courante ici que j'ai vue a été simplement Implémenter l'opérateur Inline, dans le modèle de classe définition. Alternativement, vous pouvez fournir un membre public fonction qui fait la sortie et l'invoque à partir de la opérateur Modèle de fonction. Ou vous pouvez écrire: p>

template <class Vertex>
class Edge : public IOStreamOperators<Edge<Vertex> >
{
    // ...
    void print( std::ostream& dest )
    {
        //  ...
    }
};


0 commentaires

1
votes

Je pense que c'est plus facile à comprendre si nous retirons le bruit étranger et envisagez:

friend ostream& operator<<(ostream& os, const Edge& e)
{
    // use e.whatever...
}
  • le f code> intérieur x code> est: vide f (x & x) code> li>
  • Le f code> extérieur x code> est: vide f (x & x) code> li> li> ul>

    Vous pouvez obtenir un soupçon de ceci en compilant et en regardant les symboles générés: p> xxx pré>

    appelant de GCC __ joli_fonction __ strong> de chaque Crayements: P>

    void f(X<double>&)
    void f(const X<T>&) [with T = double]
    


0 commentaires