3 votes

surcharge d'opérateurs pour les modèles dérivés imbriqués

J'ai un problème avec la surcharge de l'opérateur pour dérivés et emboîtés classe. J'ai essayé de nombreuses façons mais j'ai échoué à plusieurs reprises. Quelqu'un peut-il m'aider à résoudre ce problème ? Voici le code :

Classe A :

template <typename T>
class A {
  public:
    virtual ~A() = default;
};

template <typename T>
ostream& operator<<(ostream& out, const A<T>& a) {
  out << "in A\n";
  return out;
}

classe B :

template <typename T>
class B : public A<T> {};

template <typename T>
ostream& operator<<(ostream& out, const B<T>& b) {
  out << "in B\n";
  return out;
}

Et le code de test :

A<int> *pa = new B<int>();
B<int> *pb = dynamic_cast<B<int> *>(pa);
cout << *pa << typeid(*pa).name() << endl;
cout << *pb << typeid(*pb).name() << endl;

Et j'ai obtenu ce dont j'ai besoin grâce au résultat :

en A

1BIiE

en B

1BIiE

Puis j'ai créé une classe imbriquée qui est également dérivée de Classe A :

classe BB::B :

template <typename T>
class BB {
  public:
    class B : public A<T> {};
};

template <typename T>
ostream& operator<<(ostream& out, const typename BB<T>::B& b) {
  out << "in BB::B\n";
  return out;
}

Mais quand je teste cette classe avec le code :

A<int> *pa2 = new BB<int>::B();
BB<int>::B *pb2 = dynamic_cast<BB<int>::B *>(pa2);
cout << *pa2 << typeid(*pa2).name() << endl;
cout << *pb2 << typeid(*pb2).name() << endl;

Je n'ai obtenu qu'un résultat inattendu :

en A

N2BBIiE1BE

en A

N2BBIiE1BE

Il semble que le compilateur n'a pas spécialisé l'opérateur surchargé<< pour BB::B . Quel est le problème ici ?

2voto

Yakk Points 31636
template <typename T>
ostream& operator<<(ostream& out, const typename BB<T>::B& b);

Le type de b est dans un contexte non cultivé. Il ne déduira jamais T de cette signature.

Vous pouvez appeler cela acheter passer T explicitement. Ou vous pouvez écrire une carte de type à partir de BB<T>::B a B et devenir très fantaisiste. Mais ça n'en vaut pas vraiment la peine.


L'option facile est un opérateur Koenig.

template <typename T>
class BB {
  public:
    class B : public A<T> {
      friend ostream& operator<<(ostream& out, const B& b){
        out << "in BB::B\n";
        return out;
      }
    };
};

Cet opérateur de Koenig est une fonction non standard qui est générée pour chaque instanciation de la fonction BB<T>::B et ne peuvent être trouvés que via ADL.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X