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

C++ Discussion :

Conflit avec expressions templates


Sujet :

C++

  1. #1
    Membre régulier

    Inscrit en
    Juin 2008
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 49
    Points : 114
    Points
    114
    Par défaut Conflit avec expressions templates
    Bonsoir,

    J'ai un code utilisant des expressions templates pour une classe de vecteurs. L'implémentation n'est pas exactement la même que celle proposée par Laurent Gomila dans son tutoriel, mais le problème que j'ai rencontré se trouve aussi dans l'implémentation proposée par Laurent.

    Lors de la définition de mes opérateurs surchargés, j'ai (notation de Laurent) pour la multiplication l'opérateur suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    template <class T>BinaryOp<T, UnaryOp<double, Const>, Mult> operator *(const T& v1, double d)
    {
        return MakeMult(v1, MakeConst(d));
    }
    qui permet de construire un noeud (de l'arbre syntaxique) qui correspond à la multiplication d'un noeud (à gauche) par un nombre (à droite).

    En parallèle, j'ai une autre classe qui n'a rien à voir avec les vecteurs précédemment définis mais qui possède elle aussi des opérateurs surchargés. Notamment, un opérateur du type:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    A operator*(const A&, double);
    Et c'est là que les problèmes apparaissent. Lorsque j'essaye d'utiliser cet opérateur avec une instance de A, le compilateur (GCC 4.4.1) me dit qu'il y a un conflit et qu'il ne sait pas quelle version choisir entre la version dédiée aux vecteurs et celle spécifique à A.

    Je ne peux donc pas avoir en même temps des expressions templates et une autre classe surchargeant des opérateurs ! C'est assez ennuyant.

    Auriez-vous une solution à ce problème épineux ?

    Merci d'avance !

    Nanoc

  2. #2
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    C'est étonnant... Il me semble (je dis semble car je suis pas sur à 100% mais pas loin) que si deux fonctions conviennent et qu'une est template la régle veut que ça soit la non template qui soit appellé.
    Faute de mieux sinon faudrait introduire un namespace pour profiter du koenig lookup.

    edit : pas une confirmation mais un petit code que tu peux tester :

    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
     
    #include <iostream>
     
    template <typename T>
    void foo(const T& x)
    {
        std::cout << "template" << std::endl;
    }
     
    void foo(const int& x)
    {
        std::cout << "non-template" << std::endl;
    }
     
    int main()
    {
        foo(3);
     
        return 0;
    }
    chez moi c'est bien la non-template qui est appelé.

  3. #3
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 861
    Points
    11 861
    Par défaut
    +1 pour le koenig lookup avec un namespace. Solution élégante et efficace.

  4. #4
    Membre régulier

    Inscrit en
    Juin 2008
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 49
    Points : 114
    Points
    114
    Par défaut
    @Goten: J'aurais du préciser que la classe A est aussi template. Le souci vient de là en fait. Sans template c'est effectivement la bonne version qui est appelée.

    Je vais regarder le Koenig lookup alors. Merci.

  5. #5
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Nanoc Voir le message
    @Goten: J'aurais du préciser que la classe A est aussi template. Le souci vient de là en fait. Sans template c'est effectivement la bonne version qui est appelée.

    Je vais regarder le Koenig lookup alors. Merci.
    Effectivement : comment le compilateur peut-il s'y retrouver, la seule différence étant le type de retour de l'opérateur ? Ton code est finalement proche de celui-ci (TYPE1 et TYP2 sont définis) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    template <class T> TYPE1 operator*(const T& a, double d)
    { ... }
    template <class T> TYPE2 operator*(const T& a, double d)
    { ... }
    Lorsque tu appelles l'opérateur, tu aura forcément un conflit quelque part.

  6. #6
    Membre confirmé Avatar de TNT89
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Points : 615
    Points
    615
    Par défaut
    J'ai le même problème et pour l'instant j'utilise une solution bête :

    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
     
    template <class T>
    BinaryOp<T, UnaryOp<double, Const>, Mult>
    operator *(const Vector<T>& v1, double d)
    {
        return MakeMult(v1, MakeConst(d));
    }
     
    template <class T, ...>
    BinaryOp<T, UnaryOp<double, Const>, Mult>
    operator *(const UnaryExpression<...>& v1, double d)
    {
        return MakeMult(v1, MakeConst(d));
    }
     
    template <class T, ...>
    BinaryOp<T, UnaryOp<double, Const>, Mult>
    operator *(const BinaryExpression<...>& v1, double d)
    {
        return MakeMult(v1, MakeConst(d));
    }
    En gros tu spécifies bien que le code ne peut que recevoir des éléments compatibles avec les expressions syntaxiques et ce seulement pour un objet racine de l'arbre syntaxique...

    Mais je vais aussi voir du côté du Koening Look up, merci du conseil!!!

Discussions similaires

  1. [RegEx] Rechercher et remplacer plusieurs occurences avec expression
    Par nabab dans le forum Langage
    Réponses: 2
    Dernier message: 12/12/2005, 18h12
  2. probleme avec expression reguliere
    Par naourass dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 09/11/2005, 13h15
  3. [phpBB] Function avec le Template phpBB
    Par mangafan dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 5
    Dernier message: 27/09/2005, 17h32
  4. Réponses: 3
    Dernier message: 22/08/2005, 19h28

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