2013-03-11 3 views
3

Je crée une classe de conteneur qui implémente une liste double liée.Égalité d'itérateur

template <class T> 
class dl_list { 
public: 
    class link { 
    public: 
     T* data; 
     link *prev, *next; 
    }; 
    class iterator { 
     link* node; 
    public: 
     link* get_node() { return node; } 
     // ++, --, * operators, etc. 
    }; 
    // other stuff 
}; 

Jolie, je m'amuse avec. Mais un problème que j'ai est quand je définis mes opérateurs d'égalité pour le type d'itérateur, je dois faire une spécialisation de modèle.

template <class T> 
bool operator==(typename dl_list<T>::iterator& lhv, typename dl_list<T>::iterator rhv) { 
    return lhv.get_node() == rhv.get_node(); 
} 

ne fonctionnera pas, je dois spécialiser comme ceci:

bool operator==(typename dl_list<int>::iterator& lhv, typename dl_list<int>::iterator rhv) { 
    return lhv.get_node() == rhv.get_node(); 
} 

pour chaque type que je veux l'utiliser pour, ce qui est gênant pour des raisons évidentes. Comment puis-je contourner cela?

Répondre

3

Faire un membre de la iterator classe:

bool operator==(const interator& other) const 
{ 
    return node == other.node; 
} 
+0

fonctionne de la même manière que de surcharger ':: operator =='? Je ne veux pas avoir à appeler 'it1.operator == (it2)' explicitement. – anthropomorphic

+1

Oui. La recherche d'opérateur surchargée comprend les opérateurs membres. – Puppy

+0

Génial. Je l'ai juste essayé et ça fonctionne implicitement. 'it1 == it2' appellera' it1.operator == (it2) 'dans les coulisses. +1 merci. – anthropomorphic

2

Vous ne pouvez pas. Le compilateur ne peut pas savoir que certains T est un type imbriqué d'un autre U. Considérez

template<> class dl_list<float> { 
public: 
    typedef dl_list<int>::iterator iterator; 
}; 

Vous devez prendre le type iterator directement en tant que paramètre de modèle, ou le définir comme un membre de la classe iterator ou définir la classe iterator en dehors dl_list et il suffit de faire un typedef pour l'intérieur dl_list.

1

Easiest façon la plus propre est de définir l'opérateur dans la classe iterator:

class iterator 
{ 
    public: 
    ... 
    friend bool operator==(iterator& lhs, iterator& rhs) 
    { 
     return lhs.get_node() == rhs.get_node(); 
    } 
}; 

(Bit d'un code odeur ici - je d ont prévu get_node() d'avoir une version const, permettant le operator== d'accepter les paramètres par référence const ...)

+0

En fait maintenant que vous le faites remarquer, je ne pense pas qu'il devrait y avoir une version non-const de 'get_node()'. Cela rendrait 'node' modifiable. Je ne sais pas si je m'en soucie ou non, mais ce n'est peut-être pas une bonne chose. – anthropomorphic

+0

Non, je suis fou. Je ne devrais vraiment pas parler de programmation à 3h du matin. – anthropomorphic