Désolé pour le titre long.Pourquoi le compilateur ne peut-il pas différencier typedef et non-typedef?
J'ai un typedef dans une liste de classe:
template <typename T>
class List {
// Think of a class Iter_ with ListElem *pCurrentPos and List *pList
typedef const Iter_ const_iterator;
const_iterator cbegin() const;
};
et la définition en dehors de la classe, mais à l'intérieur du fichier d'en-tête.
template <typename T>
typename List<T>::const_iterator List<T>::cbegin() const {}
Cela produit le C2373 d'erreur: Redefinition; different type modifiers
Je réécris la fonction comme ceci:
template <typename T>
const typename List<T>::Iter_ List<T>::cbegin() const {}
et l'erreur a disparu; le programme compile correctement. (Repensez le fait que je ne retourne rien dans ces exemples, c'est sans importance pour l'exemple.)
Quelle est l'interprétation du compilateur avec la version erronée qui empêche la compilation réussie que la deuxième version ne fonctionne pas, et comment puis-je remédier à cela?
Plus code
J'utilise VS2008
Le (plus complète) exemple de code Je programme actuellement:
template <typename T>
class List
{
public:
// Forward declaration.
class Iter_;
private:
/////////////////////////////////////////////////////////
// ListElem
/////////////////////////////////////////////////////////
struct ListElem
{
T data;
// Doubly-linked list.
ListElem *next;
ListElem *prev;
};
class ListException {};
////////////////////////////////////////////////////////
// List Members
////////////////////////////////////////////////////////
// Point to first elem.
ListElem *head_;
// Point to last elem.
ListElem *tail_;
public:
//////////////////////////////////////////////////////////
// Typedefs
//////////////////////////////////////////////////////////
typedef Iter_ iterator;
typedef const Iter_ const_iterator;
//////////////////////////////////////////////////////////
// Iterator class
//////////////////////////////////////////////////////////
class Iter_
{
public:
Iter_(ListElem *pCurr, List *pList)
: pCurr_(pCurr), pList_(pList)
{ }
T& operator*()
{
if(*this == pList_->end())
throw ListException();
else
return pCurr_->data;
}
private:
ListElem *pCurr_;
List *pList_;
};
iterator begin();
iterator end();
const_iterator cbegin() const;
const_iterator cend() const;
};
template <typename T>
List<T>::List()
: head_(0), tail_(0), size_(0)
{ }
template <typename T>
List<T>::~List()
{
//this->clear();
}
template <typename T>
List<T>::List(List const& other)
: size_(other.size_)
{
//this->clone(other);
}
template <typename T>
List<T>& List<T>::operator=(List const& other)
{
size_ = other.size_;
//this->clone(other);
}
// Compiles ok
template <typename T>
typename List<T>::iterator List<T>::begin()
{
if(!head_)
head_ = new ListElem();
return iterator(head_, this);
}
// Compiles ok
template <typename T>
typename List<T>::iterator List<T>::end()
{
return iterator(tail_, this);
}
// Compiler error
template <typename T>
typename List<T>::const_iterator List<T>::cbegin() const
{
return const_iterator(head_, this);
}
// Compiles ok
template <typename T>
typename const List<T>::Iter_ List<T>::cend() const
{
return const_iterator(tail_, this);
}
Où (et comment) 'Iter_' est-il défini? – atzz
comeau le compile juste bien (sauf pour 'typename const Liste :: Iter_ etc ...' qui devrait être 'const typename etc ...') –
lijie
@atzz: J'ai ajouté le code supplémentaire. – IAE