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 :

Problème de typename


Sujet :

Langage C++

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut Problème de typename
    Hello,

    Voici un petit code qui ne compile pas :

    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
    #include <type_traits>
    
    template <typename T>
    struct MaClasse
    {
    	std::conditional<std::is_class<T>::value, typename T::IntT, T> monMembre; // long, n'est-ce pas ?
    };
    
    struct Foo
    {
    	typedef int IntT;
    };
    
    int main()
    {
    	std::is_class<int>::value;	// OK
    	std::is_class<Foo>::value;	// OK
    
    	MaClasse<int> MonInstance_1;	// KO !!!
    	MaClasse<Foo> MonInstance_2;	// OK
    
    	std::conditional<true,  Foo::IntT, int> MonInstance_3;	// OK
    	std::conditional<false, Foo::IntT, int> MonInstance_4;	// OK
    }
    gcc râle sur la ligne 6 :

    erreur: ‘int’ is not a class, struct, or union type

    Le problème vient de ce qui est indiqué en rouge : le compilateur va semble-t-il évaluer les deux expressions du std::conditional, même s'il ne sert que d'une.

    Cela restreint quelque peu l'intérêt de std::is_class...

    Quelqu'un aurait-il une idée de la manière dont je pourrais contourner ce problème ?

    Merci.

  2. #2
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Par défaut
    Salut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::conditional<std::is_class<T>::value, typename T::IntT, T> monMembre;
    Si tu remplaces T par int, c'est normal que ça ne compile pas puisque c'est comme si tu écrivais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::conditional<std::is_class<T>::value, typename int::IntT, T> monMembre;
    Et int n'est pas une classe ayant pour membre IntT

    Après je pense que ça doit quand même être faisable

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Oui, mais quand c'est un int, le compilateur ne devrait pas chercher à parser cette alternative de l'opérateur ternaire statique qu'est std::conditional !

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Bon, j'ai trouvé la parade, mais c'est lourdingue :


    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
    #include <type_traits>
     
    template <typename T, bool IsClass>
    struct RealType;
     
    template <typename T>
    struct RealType <T, true>
    {
    	typedef typename T::IntT VeryRealType;
    };
     
    template <typename T>
    struct RealType <T, false>
    {
    	typedef T VeryRealType;
    };
     
     
     
    template <typename T>
    struct MaClasse
    {
    	typename RealType<T, std::is_class<T>::value>::VeryRealType monMembre;	// long, n'est-ce pas ?
    };
     
    struct Foo
    {
    	typedef int IntT;
    };
     
    int main()
    {
    	std::is_class<int>::value;		// OK
    	std::is_class<Foo>::value;		// OK
     
    	MaClasse<int> MonInstance_1;	// KO !!!
    	MaClasse<Foo> MonInstance_2;	// OK
     
    	std::conditional<true,  Foo::IntT, int> MonInstance_3;
    	std::conditional<false, Foo::IntT, int> MonInstance_4;	
    }

  5. #5
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Par défaut
    le compilateur ne devrait pas chercher à parser cette alternative de l'opérateur ternaire statique qu'est std::conditional !
    Il ne devrait pas mais visiblement il le fait sinon le compilo indiquerait pas ça enfin je pense je m'y connais moins que toi toute façon

  6. #6
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Si il doit parser tout les paramètres template, ce que tu veux faire c'est ce que fait boost::mpl::eval_if.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Ça m'a l'air de faire la même chose que std::conditional, non ?

  8. #8
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Non, std::conditional c'est boost::mpl::if_. Plus exactement c'est if_c, et toi ce que tu veux, si tu veux utiliser un bool, c'est eval_if_c. Pour la différence entre les quatre, je te laisse voir la description dans la man (4 lignes à lire en tout) : http://www.boost.org/doc/libs/1_46_0...eval-if-c.html (je te laisse trouver les autres pages )

    Plus fondamentalement, on retrouve ici la force de boost::mpl : les méta-fonctions. Ce sont elles qui te permettent de faire ce que tu veux (ie évaluer seulement "l'instruction" liée au résultat de la condition). Pour tout les détails voir le livre de David Abrahams.

Discussions similaires

  1. [WebForms][2.0] deux ObjectDataSource de même TypeName posent problème
    Par stephane.net dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 17/11/2006, 09h55
  2. Problème supposément de typename
    Par vdumont dans le forum C++
    Réponses: 11
    Dernier message: 24/03/2006, 15h45
  3. Problème d'installation oracle 8.1.7 sous NT
    Par Anonymous dans le forum Installation
    Réponses: 7
    Dernier message: 02/08/2002, 14h18
  4. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10
  5. Réponses: 6
    Dernier message: 25/03/2002, 21h11

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