6

これは完全に機能します:

list<int> l;
list<int>::const_iterator it;
it = l.begin();
list<int>::iterator it2;
it2 = l.begin();

私が得られないのは、バージョンまたはバージョンlistを返さなければならないことを「知っている」方法です。iterator begin()const_iterator begin() const

コンテナー (トライ) のイテレーターを実装しようとしていますが、この問題が発生しています。C++ は戻り値の型による差別化を処理するべきではありませんか (変なトリックを使用する場合を除く)。

ここにいくつかのコードと私が得るコンパイラエラーがあります:

MyTrie<T>は、任意の型を含むことができるテンプレート化されたトライです。Trie<int>::iter非定数イテレータと定数イテレータがありますTrie<int>::const_iter。Trie クラスで宣言 (および定義) されますiter begin()const_iter begin() const

Trie<int> t;
Trie<int>::const_iter it;
it = t.begin();

エラー :

../test/trie.cpp:181: error: no match for 'operator=' in 'it = Trie<T>::begin() [with T = int]()'
[..path..]/Trie.h:230: note: candidates are: Trie<int>::const_trie_iterator& Trie<int>::const_trie_iterator::operator=(const Trie<int>::const_trie_iterator&)

したがって、の非 const バージョンbeginは使用されていないと思います。

operator=(const Trie<T>::const_trie_iterator&)非定数イテレータのメソッドを作成することを考えましたが、 STDlib にそれが表示されず、イテレータを const_cast する必要があります。私は何をすべきか?

4

2 に答える 2

6

標準コンテナーでは、非 const イテレーターは暗黙的に const_iterator に変換可能です。返される型は、呼び出されたオブジェクト/参照の const-ness のみに基づいていbegin()ます。あなたの場合はiterator、後の割り当てを可能にする変換があります。

特に、23.2.1 General Container Requirements の表 96 では、 はX::iteratorに変換可能でなければならないと述べていX::const_iteratorます。

于 2012-09-28T20:33:50.380 に答える
3

リストが const の場合とそうでない場合の 2 つの begin メソッドが定義されているため、list は返すイテレータの種類を認識しています。宣言は次のようになります。

template<class T>
class list {
public:
    iterator<T> begin();
    const_iterator<T> begin() const;
}

次の例では、リストが const ではないため、最初の非 const イテレータが返されます。

void doSomething(list<int> &myList) {
    iterator<int> i = myList.begin();
    ...
}

次の例では、リストが const として宣言されているため、代わりに const_iterator を返す 2 番目のバージョンの begin が使用されます。

void doSomethingElse(const list<int> &myList) {
    const_iterator<int> i = myList.begin();
    ....
}

もちろん、イテレータは常に const_iterator にキャストできるため、どちらの例でも i を const_iterator として宣言できますが、2 番目の例で i をイテレータとして宣言しようとすると、const_iterator であるためエラーが発生します。イテレータとして暗黙的にキャストすることはできません。

于 2012-09-28T20:46:14.360 に答える