Partage
  • Partager sur Facebook
  • Partager sur Twitter

Héritage template et membre introuvable

Sujet résolu
    18 août 2019 à 10:44:46

    Salut !

    Soit le code suivant :

    template <typename T>
    class A
    {
    protected:
    	T x;
    };
    
    template <typename T>
    class B:public A<T>
    {
    public:
    	void test()
    	{
    		x = 3;
    	}
    };

    J'ai un visual C++ 2019 sous la main : 

    Erreur :  error C3861:  'x' : identificateur introuvable  (dans la fonction test)

    Pourtant, x est protected dans la classe mère, et est à portée.

    Et cela compile bien si j'explicite d'ou vient x :

    template <typename T>
    class A
    {
    protected:
    	T x;
    };
    
    template <typename T>
    class B:public A<T>
    {
    public:
    	void test()
    	{
    		A<T>::x = 3;
    	}
    };
    


    Par contre... l'écriture va être lourde... Il n'y aurait pas moyen de mettre, je ne sais moi moi, un "using" ou je ne sais quoi qui me permette de dire dans la classe B "si je te parle de x, tu vas chercher A<T>::x" ?

    merci !

    -
    Edité par Fvirtman 18 août 2019 à 10:45:31

    • Partager sur Facebook
    • Partager sur Twitter

    Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

      18 août 2019 à 13:39:14

      Salut,

      Oui, c'est un des rares cas où il est nécessaire de faire appel explicitement à A<T>::x) pour une vague raison de "argument dependant lookup".

      "Long story short": le type de la classe de base (A) dépend du paramètre template de la classe dérivée (B), et il faut aider le compilateur à s'y retrouver ;)

      Ceci étant dit, une donnée membre ne devrait jamais être dans l'accessibilité protégée : soit "tout le monde" y a accès et on la place dans l'accessibilité publique, soit, on la place dans l'accessibilité privée, et, si seules les classes dérivées sont susceptibles de manipuler la donnée, on fournit les fonctions qui vont bien (dans l'accessibilité protégée), sous une forme proche de

      template <typename T>
      class A{
      protected:
          void change(T newVal){
              x_ = newVal;
          }
          T const & ask() const{
              return x_;
          }
      private:
          T x_;
      };
      tempalte <typename T>
      class B : public A<T>{
      public:
         void test(T t){
             A<T>::change(t);
         }
      };

      Ou bien, tu peux forcer à l'utilisation de la fonction qui t'intéresse, sous une forme proche de

      tempalte <typename T>
      class B : public A<T>{
      public:
         void test(T t){
             change(t); // ca marche
         }
      protected: /* parce que l'on ne va pas exposer publicquement
                  * une fonction interne
                  */
          using A<T>::change; /* (par contre, cette directive
                               * pourrait prendre place dans
                               *  l'accessibilité privée)
                               */
         
      };

      -
      Edité par koala01 18 août 2019 à 13:43:50

      • Partager sur Facebook
      • Partager sur Twitter
      Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
        18 août 2019 à 17:16:12

        Merci pour vos réponses ! :)
        • Partager sur Facebook
        • Partager sur Twitter

        Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

        Héritage template et membre introuvable

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown