Pb de syntaxe avec une methode template d'une classe template. [Résolu]

Signaler
Messages postés
17
Date d'inscription
jeudi 9 décembre 2004
Statut
Membre
Dernière intervention
20 février 2009
-
gaspos
Messages postés
17
Date d'inscription
jeudi 9 décembre 2004
Statut
Membre
Dernière intervention
20 février 2009
-
Bonjour,
voici une classe template dont l'une des méthode a un type template en plus :

template <class type1> struct foo 
   { 
   // première methode sans type template supplementaire 
   // dont l'implementation est donnée plus bas 
   int func1 ( type1 & x ) ; 

   // deuxième methode avec un type template supplementaire (type2) 
   // dont le code est inline 
   template <class type2> 
      int func2 ( type1 & x , type2 & y ) 
         { 
         return( sizeof( x )+sizeof( y ) ) ; 
         } 

   // troisième methode avec un type template supplementaire (type2) 
   // dont l'implementation est donnée plus bas 
   template <class type2> 
      int func3 ( type1 & x , type2 & y ) ; 
   } ;

// implementation de la première méthode : OK
template <class type1> int foo<type1>::func1 ( type1 & x ) 
   { 
   return( sizeof( x )*2 ) ; 
   }

// implementation de la troisème méthode :KO !
template <class type1,class type2>
int foo<type1>::func3<type2> ( type1 & x , type2 & y ) 
   { 
   return( sizeof( x )*sizeof( y ) ) ; 
   }

La partie implémentation de func3 ne compile pas...
C'est la première fois que je me retrouve dans cette situation, et je n'ai pas la moindre idée
de la syntaxe qui convient pour déclarer ce genre de chose.
La méthode func2 qui est déclarée en inline compile sans problème.
La méthode func1 qui n'a pas de type inline supplementaire aussi.
Si quelqu'un a une idée pour func3, je suis preneur !

Pour info, je compile avec Visual C++ 2005.
Peut-être est-ce lui le coupable...

Merci d'avance
Gaspos

7 réponses

Messages postés
202
Date d'inscription
dimanche 18 mai 2003
Statut
Membre
Dernière intervention
6 mars 2010

il y a une erreur dans ton code il faut définir les 2 classes du templates. ça marche j'ai essayé sur Visual 2008.

à la définition de la classe c'est pas :

template <typename output>
friend output & operator<< ( output & o , const foo & t ) ;


mais :

template <typename Value, typename output> // il faut redéfinir template Value
friend output & operator<< ( output & o , const foo & t ) ;
Messages postés
202
Date d'inscription
dimanche 18 mai 2003
Statut
Membre
Dernière intervention
6 mars 2010

La 3eme fonction s'implémente comme ça :

template <class type1="">
template <class type2="">
int foo<type1>::func3( type1 & x , type2 & y )
{
return( sizeof( x )*sizeof( y ) ) ;
}
</type1></class></class>
Messages postés
202
Date d'inscription
dimanche 18 mai 2003
Statut
Membre
Dernière intervention
6 mars 2010

désolé pour le formatage

template <class type1>
template <class type2>
int foo<type1>::func3( type1 & x , type2 & y )
{
return( sizeof( x )*sizeof( y ) ) ;
}
Messages postés
17
Date d'inscription
jeudi 9 décembre 2004
Statut
Membre
Dernière intervention
20 février 2009

Wow ! Super merci !

En fait j'avais trouvé la réponse dans l'excellent "c++ template, the complete guide" de Vandervoorde et Josuttis aux éditions Addison-Wesley.

Mais bien sûr, l'arbre cachait la forêt. Voici le challange de niveau 2, la même chose avec une fonction friend : 

template <typename Value> class foo
    {
    public:
        template <typename output>
            friend output & operator<< ( output & o , const foo & t )  //  ça marche !
                {
                o << t.i ;
                return( o ) ;
                }
    private:
        Value i ;
    } ;

Mais comment déporter la définition de l'operateur << comme on l'a fait pour fonc3 

Gaspos

 
Messages postés
202
Date d'inscription
dimanche 18 mai 2003
Statut
Membre
Dernière intervention
6 mars 2010

un peu plus dur cette fois ;)

dans ta class foo tu déclare ta free fonction comme étant friend :

template <class type1> struct foo
{
// définition de ta classe ....

template<class type1, class output>
friend output& operator<< (output& o , foo<type1>& f);

}

puis du implémente ta fonction comme ceci :

template<class type1, class output>
output& operator<< (output& o, foo<type1>& f)
{
o << f.i;
return o;
}

et Voila...
Messages postés
17
Date d'inscription
jeudi 9 décembre 2004
Statut
Membre
Dernière intervention
20 février 2009

Merci de ta prompte réponse !
J'avais déjà pensé à cette syntaxe mais ça ne marche pas :

Avec ce code :

template <typename Value> class foo
    {
    public:
        template <typename output>
            friend output & operator<< ( output & o , const foo & t ) ;
    private:
        Value i ;
    } ;



template <typename Value,typename output>
    output & operator<< ( output & o , const foo<Value> & t )
        {
        o << t.i ;  // ERREUR : ne peut accéder à un membre privé
        return( o ) ;
        }


le compilo me renvoie l'erreur en rouge au dessus.
Tout s'explique avec cette tentative :

template <typename Value> class foo
    {
    public:
        template <typename output>
            friend output & operator<< ( output & o , const foo & t )
                { // implémentée ici
                o << t.i ;
                return( o ) ;
                }
    private:
        Value i ;
    } ;



template <typename Value,typename output>
    output & operator<< ( output & o , const foo<Value> & t )
        { // et encore une fois ici --> on devrait avoir une erreur !
        o << t.i ;
        return( o ) ;
        }


J'ai toujours la même erreur alors que je m'attendais à ce que le compilo me dise que l'opérateur << était déjà implementé. J'en conclue qu'il ne fait pas le lien entre la déclaration de la fonction amie au sein de la classe et celle implémentée plus bas. Ce qui explique l'erreur : il ne sait pas que cette fonction est celle qui avait désignée comme amie et du coup, interdit l'accès aux membres privés.

Ce qui est encore plus bizarre, c'est que si, dans la première version du code, on vire le "private", ça marche et l'operateur << est bien invoqué. Ce qui signifie que dans ce cas là, le compilo sait bien aller chercher cette fonction.

Il faudrait essayer avec gcc pour voir si c'est un pb d'implementation de la norme c++ par Crimosoft...

Hadrien
Messages postés
17
Date d'inscription
jeudi 9 décembre 2004
Statut
Membre
Dernière intervention
20 février 2009

Mais bon sang, mais c'est bien sûr !

L'opérateur << n'est pas une méthode de la classe, donc il n'hérite pas de son paramètre de template.
Du coup, ça marche dans mon code aussi !
Je m'en vais publier ce code sous peu (qui est enfin présentable grâce à toi).

Le fait est que c'est un peu étrange cette déclaration de fonction amie depuis l'interieur de la déclaration d'une classe.

encore merci !
Hadrien