IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

spécialisation d'un template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 12
    Par défaut spécialisation d'un template
    Je travaille sur un bout code ayant besoin de spécialiser un template suivant son nombre de paramètres. Il ne compile pas et il a la "forme" de ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    // NE COMPILE PAS PAS
     
    #include <iostream>
    using namespace std;
     
    template< typename T = void, typename U = void >
    struct Dummy
    {
    	void Hello(T t, U u);
    };
     
    template< typename T, typename U >
    void Dummy< T, U >::Hello(T t, U u)
    {
    	cout << t << " " << u << endl;
    }
     
    template< typename T >
    struct Dummy< T >
    {
    	void Hello(T t);
    };
     
    template< typename T >
    void Dummy< T >::Hello(T t)
    {
    	cout << t << endl;
    }
     
    template< >
    struct Dummy< >
    {
    	void Hello();
    };
     
    template< >
    void Dummy< >::Hello()
    {
    	cout << "-" << endl;
    }
     
    int main(int argc, char** argv)
    {
    	Dummy< int, double >().Hello(5,0.1);
    	Dummy< int >().Hello(5);
    	Dummy< >().Hello();
    }
    Messages de g++ :

    main.cpp:64: erreur: template-id `Hello<>' for `void Dummy<void, void>::Hello()' does not match any template declaration
    main.cpp:64: erreur: déclaration de fonction invalide

    Ces deux autres codes compilent néanmoins très bien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    // COMPILE...
     
    #include <iostream>
    using namespace std;
     
    template< typename T = void, typename U = void >
    struct Dummy
    {
    	void Hello(T t, U u);
    };
     
    template< typename T, typename U >
    void Dummy< T, U >::Hello(T t, U u)
    {
    	cout << t << " " << u << endl;
    }
     
    template< typename T >
    struct Dummy< T >
    {
    	void Hello(T t);
    };
     
    template< typename T >
    void Dummy< T >::Hello(T t)
    {
    	cout << t << endl;
    }
     
    int main(int argc, char** argv)
    {
    	Dummy< int, double >().Hello(5,0.1);
    	Dummy< int >().Hello(5);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    // COMPILE
    #include <iostream>
    using namespace std;
     
    template< typename T = void, typename U = void >
    struct Dummy
    {
    	void Hello(T t, U u)
    	{
    		cout << t << " " << u << endl;
    	}
    };
     
    template< typename T >
    struct Dummy< T >
    {
    	void Hello(T t)
    	{
    		cout << t << endl;
    	}
    };
     
    template< >
    struct Dummy< >
    {
    	void Hello()
    	{
    		cout << "-" << endl;
    	}
    };
     
    int main(int argc, char** argv)
    {
    	Dummy< int, double >().Hello(5,0.1);
    	Dummy< int >().Hello(5);
    	Dummy< >().Hello();
    }
    Ou est l'erreur dans la spécialisation de Dummy sans paramètre de la première version ?

    Merci d'avance

  2. #2
    screetch
    Invité(e)
    Par défaut
    Salut,

    ta structure Dummy<void void> est deja entierement specialisee

    pour la definition,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Dummy< void, void >::Hello()
    {
    	cout << "-" << endl;
    }
    fonctionne.

    Si tu places le devant, il va s'emmeler les pinceaux. Je ne connais pas la raison profonde de cela (en tous cas je sais pas l'exprimer avec mes mots a moi)

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 12
    Par défaut
    Ta solution fonctionne mais un nouveau problème est survenu... et le code ne compile plus.
    Dummy à besoin de la définition de Crazy et vice versa :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
     
    // NE COMPILE PAS
    // Les pointeurs man et woman sont censés être initialisés dans main
     
    template< typename T = void, typename U = void >
    struct Dummy;
     
    /** Crazy template and his specialisations */
    template< typename T = void, typename U = void >
    struct Crazy
    {
    	Dummy< T, U >* man;	
    	void Hello(T t, U u);
    };
     
    template< typename T, typename U >
    void Crazy< T, U >::Hello(T t, U u)
    {
    	man->Bingo(t,u);
    }
     
    template< typename T >
    struct Crazy< T >
    {
    	Dummy< T >* man;
    	void Hello(T t);
    };
     
    template< typename T >
    void Crazy< T >::Hello(T t)
    {
    	man->Bingo(t);
    }
     
    template< >
    struct Crazy< >
    {
    	Dummy< >* man;
    	void Hello();
    };
     
    void Crazy< >::Hello()
    {
    	man->Bingo();
    }
     
    /** Dummy template and his specialisations */
    template< typename T, typename U >
    struct Dummy
    {
    	Crazy< T, U >* woman;
    	void Hello(T t, U u);
    	void Bingo(T t, U u);
    };
     
    template< typename T, typename U >
    void Dummy< T, U >::Hello(T t, U u)
    {
    	woman->Hello(t,u);
    }
     
    template< typename T, typename U >
    void Dummy< T, U >::Bingo(T t, U u)
    {
    	// ...
    }
     
    template< typename T >
    struct Dummy< T >
    {
    	Crazy< T >* woman;
    	void Hello(T t);
    	void Bingo(T t);
    };
     
    template< typename T >
    void Dummy< T >::Hello(T t)
    {
    	woman->Hello(t);
    }
     
    template< typename T >
    void Dummy< T >::Bingo(T t)
    {
    	// ...
    }
     
    template< >
    struct Dummy< >
    {
    	Crazy< >* woman;
    	void Hello();
    	void Bingo();
    };
     
    void Dummy< >::Hello()
    {
    	woman->Hello();
    }
     
    void Dummy< >::Bingo()
    {
    	// ...
    }
     
    int main(int argc, char** argv)
    {
    	// ...
    }
    Messages de g++ :

    main.cpp: In member function `void Crazy<void, void>::Hello()':
    main.cpp:72: erreur: invalid use of undefined type `struct Dummy<void, void>'
    main.cpp:34: erreur: declaration of `struct Dummy<void, void>'

    Bien sur il n'y a aucun problème si je compile ceci à la place :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
     
    // NE COMPILE PAS
    // Les pointeurs man et woman sont censés être initialisés dans main
     
    template< typename T = void, typename U = void >
    struct Dummy;
     
    /** Crazy template and his specialisations */
    template< typename T = void, typename U = void >
    struct Crazy
    {
    	Dummy< T, U >* man;	
    	void Hello(T t, U u);
    };
     
    template< typename T, typename U >
    void Crazy< T, U >::Hello(T t, U u)
    {
    	man->Bingo(t,u);
    }
     
    template< typename T >
    struct Crazy< T >
    {
    	Dummy< T >* man;
    	void Hello(T t);
    };
     
    template< typename T >
    void Crazy< T >::Hello(T t)
    {
    	man->Bingo(t);
    }
     
    /** Dummy template and his specialisations */
    template< typename T, typename U >
    struct Dummy
    {
    	Crazy< T, U >* woman;
    	void Hello(T t, U u);
    	void Bingo(T t, U u);
    };
     
    template< typename T, typename U >
    void Dummy< T, U >::Hello(T t, U u)
    {
    	woman->Hello(t,u);
    }
     
    template< typename T, typename U >
    void Dummy< T, U >::Bingo(T t, U u)
    {
    	// ...
    }
     
    template< typename T >
    struct Dummy< T >
    {
    	Crazy< T >* woman;
    	void Hello(T t);
    	void Bingo(T t);
    };
     
    template< typename T >
    void Dummy< T >::Hello(T t)
    {
    	woman->Hello(t);
    }
     
    template< typename T >
    void Dummy< T >::Bingo(T t)
    {
    	// ...
    }
     
    int main(int argc, char** argv)
    {
    	// ...
    }
    Une idée ?

  4. #4
    screetch
    Invité(e)
    Par défaut
    cela depend de l'ordre ou tu definis les fonctions je pense. Je n'ai plus le compilo sous la main donc je ne peux pas verifier.

    Mais en gros quand tu fais man->kekchose() alors il faut que le type de man soit connu, donc que sa definition (du type, pas de la variable) soit avant.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 12
    Par défaut
    C'est bien le problème, Crazy et Dummy ont besoin reciproquement l'un de l'autre, donc si change l'ordre le problème sera toujours là. J'ai essayé de prédéfinir le template placé en seconde position mais le cas du < > ne fonctionne pas contrairement aux autres... :S

  6. #6
    screetch
    Invité(e)
    Par défaut
    mets les definitions de classe en haut et les definitions de methodes en bas. Fais toujours ca ^^

    si possible, pour ranger, mets les definitions de classe dans un .h, les definitions de methode dans un .inl, inclus le .inl apres le .h, et inclus dans le .inl le .h qui manque

    en gros
    fichier dummy.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    /* predecl */
    template< typename T U >
    struct Crazy<T,U>;
     
    struct Dummy< >
    {
    };
     
    struct Dummy< >
    {
    };
     
    struct Dummy< void void >
    {
    };
     
    #include "dummy.inl"
    fichier crazy.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    /* predecl */
    template< typename T U >
    struct Dummy<T,U>;
     
    struct Crazy< >
    {
    };
     
    struct Crazy< >
    {
    };
     
    struct Crazy< void void >
    {
    };
     
    #include "crazy.inl"
    fichier dummy.inl
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    /* besoin de crazy */
    #include "crazy.h"
     
    Dummy< >::GoodBye()
    {
    };
     
    Dummy< void void >::GoodBye()
    {
    }
    fichier crazy.inl
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    /* besoin de dummy */
    #include "dummy.h"
     
    Crazy< void void >::Hello()
    {
    }
     
    Crazy< void void >::Hello()
    {
    }
    sans oublier les include gards qui vont bien.
    Inclus dummy.h crazy.h dans ton main.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Template] spécialisation partielle des template
    Par vikki dans le forum Langage
    Réponses: 9
    Dernier message: 10/11/2008, 16h29
  2. Réponses: 4
    Dernier message: 04/09/2008, 10h58
  3. Spécialisation de classe Template
    Par mister3957 dans le forum Langage
    Réponses: 2
    Dernier message: 21/07/2008, 15h35
  4. Heritage-Spécialisation d'un template
    Par remitbo dans le forum Langage
    Réponses: 9
    Dernier message: 25/01/2008, 08h36
  5. Problème de spécialisation de fonction template membre
    Par Davidbrcz dans le forum Langage
    Réponses: 4
    Dernier message: 29/12/2007, 20h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo