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 :

Deux versions d'une fonction template avec argument const/non const


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut Deux versions d'une fonction template avec argument const/non const
    Re-bonjour à toutes et à tous !
    Je fais passer un visiteur sur tous les noeuds d'un arbre en utilisant une fonction de parcours. Mon mon grand ami compilateur n'aime pas du tout le code suivant :

    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
    template <typename Visitor, typename T>
    Visitor& pre_order_DFS(Visitor& v, Node<T> const& node){
    	v.visit(node) 
            // ...
    	return v;
    }
     
    template <typename Visitor, typename T>
    Visitor& pre_order_DFS(Visitor& v, Node<T> & node){
    	v.visit(node) 
            // ...
    	return v;
    }
     
    template<typename Node>
    class AllelicStateInheritance{
     
    public:
    	void visit(Node & node) {
                  // ...
            }
    }
    Il me dit que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    traversal.h:57:2: error: binding ‘const Node<traversal::CoalescentToDatasetConnector<Coords, unsigned int, genet::Marker_Descriptor<unsigned int> > >’ to reference of type ‘Node<traversal::CoalescentToDatasetConnector<Coords, unsigned int, genet::Marker_Descriptor<unsigned int> > >&’ discards qualifiers
      v.visit(node);
      ^
    traversal.h:301:7: note:   initializing argument 1 of ‘void traversal::AllelicStateInheritance<Node>::visit(Node&) [with Node = Node<traversal::CoalescentToDatasetConnector<Coords, unsigned int, genet::Marker_Descriptor<unsigned int> > >]
    Ce que j'ai traduit par "désolé mon grand, j'arrive pas à envoyer une référence non constante dans la version non constante de la fonction de parcours".
    Est-ce que j'ai juste dans la traduction ? Si oui, quelqu'un pourrait m'aiguiller vers la solution technique adaptée ?
    Merci à vous !

    PS : j'ai trouvé ça, c'est adapté ? Evidemment j'ai pour l'instant rien compris, je me renseigne...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template <typename Visitor, typename T>
    typename std::enable_if< std::is_same<Aggregate,
                                       typename std::remove_const<T>::type 
                                      >::value
                           >::type
    visit( Visitor & v, T & s ) {  // T can only be Aggregate or Aggregate const
        v(s.i);
        v(s.d);   
    }

  2. #2
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Bonjour,

    Tu as peut-être raté un copier-coller, car tes deux modèles de fonction pre_order_DFS(Visitor& v, Node<T> const& node) ont exactement les mêmes arguments, avec des const exactement aux mêmes endroits.

    En tout cas, dans ces fonctions, ton paramètre node est une référence constante.
    Par contre, dans ta fonction visit(Node & node), ton paramètre node est une référence non constante.
    Tu coup, quand tu fais v.visit(node), ton compilateur proteste, et c'est normal.
    D'ailleurs, si tu relis bien le message du compilateur, il te dit qu'il refuse de lier une référence non constante Node<blablabla>& à un type constant const Node<blablabla>

    Citation Envoyé par Seabirds Voir le message
    PS : j'ai trouvé ça, c'est adapté ? Evidemment j'ai pour l'instant rien compris, je me renseigne...
    http://stackoverflow.com/questions/7...n-const-method
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template <typename Visitor, typename T>
    typename std::enable_if< std::is_same<Aggregate,
                                       typename std::remove_const<T>::type 
                                      >::value
                           >::type
    visit( Visitor & v, T & s ) {  // T can only be Aggregate or Aggregate const
        v(s.i);
        v(s.d);   
    }
    Pour faire simple :
    • std::enable_if<true>::type, c'est pareil que void.
    • std::enable_if<false>::type, ça ne correspond à rien car la structure std::enable_if<false> n'a pas de membre type.
    • Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      std::enable_if<
          std::is_same<
              Aggregate,
              typename std::remove_const<T>::type
          >::value
      >::type
      correspond à void si T est égal à Aggregate ou Aggregate const, mais ne correspond à rien sinon.
    • Quand tu écris visit(truc, chose), lorsque le compilateur cherchera le modèle de fonction ou la fonction à appeler, si le paramètre chose ne peut pas être de type Aggregate& ou Aggregate const&, ton modèle de fonction
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      template <typename Visitor, typename T>
      typename std::enable_if<
          std::is_same<
              Aggregate,
              typename std::remove_const<T>::type
          >::value
      >::type visit( Visitor & v, T & s )
      ne sera pas retenu.


    Pour plus de détails :
    http://cpp.developpez.com/faq/cpp/?p...-ce-que-SFINAE
    http://www.cplusplus.com/reference/t...its/enable_if/

  3. #3
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Holalalalala, faut que je dorme moi.
    J'ai corrigé le const dans le message, mais mon code était correct (sur ce point). Le visit était ok, par contre j'ai ajouté un accès non constant aux enfants du node pour l'utiliser dans le parcours. Le problème venait de là.
    Je vais de ce pas me plaindre à Morphée et me consoler à coup d'oreiller.
    Merci de ta réponse et de tes explications !!!

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

Discussions similaires

  1. Surchargé une fonction template avec template
    Par SKone dans le forum Langage
    Réponses: 2
    Dernier message: 12/10/2014, 20h00
  2. Réponses: 9
    Dernier message: 24/03/2011, 21h54
  3. Réponses: 11
    Dernier message: 20/11/2010, 13h08
  4. Réponses: 8
    Dernier message: 07/04/2008, 12h02
  5. Réponses: 4
    Dernier message: 24/08/2007, 15h56

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