長いタイトルを残して申し訳ありません。コンパイラがtypedefとnon-typedefを区別できないのはなぜですか?
私は、クラスリストのtypedefを持っている:
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;
};
とクラスの外ではなく、ヘッダファイル内の定義を。
template <typename T>
typename List<T>::const_iterator List<T>::cbegin() const {}
これはエラーC2373生成します。私はそうのような機能を書き直しRedefinition; different type modifiers
を:
template <typename T>
const typename List<T>::Iter_ List<T>::cbegin() const {}
とエラーがなくなっています。プログラムは正しくコンパイルされます。
2番目のバージョンでは成功しないコンパイルを妨げる誤ったバージョンのコンパイラはどのようなものですか。どのようにすればよいでしょうか?この例では、これを改善する?
私は現在、プログラミングてるVS2008
(フラー)のコード例を使用してい
もっとコード:
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);
}
ここで(どのように) 'Iter_'が定義されていますか? – atzz
comeauはそれをちゃんとコンパイルします( 'typename const List :: Iter_ etc ...' 'const typename etc ...')。 –
lijie
@atzz:追加コードを追加しました。 – IAE