const_reverse_iteratorは非constなコンテナからは返せない?
またC++の深遠なる世界にハマる。
コンテナが返すイテレータは、それと同じタイプのイテレータであることしか保障されていないらしい。constなコンテナならconstイテレータ、非constなら非constイテレータ。
http://forums.belution.com/ja/cpp/000/010/48s.shtml
VC/GCCの実装ではiteratorとconst_iteratorは比較互換が(たまたま)あるために、非constなイテレータで書き換えが必要ないときにconst_iteratorを使うことは可能だったが、規格的には禁止も保証もされていないundocumentな動作である、と。
つまり、非constなコンテナは、どこまでも非constを貫け、と…。
これは誤認であった。(2006/11訂正)*1
C++仕様的には、非constからconst方向へのイテレータの変換は保証されており、できないのはVC/GCCのバグだったらしい。
ロストしないように引用しておく。
Re[4]:const_reverse_iteratorでエラー #00001063 (Reply to #00001054) 名前 YuO (メール) 日時 2003-06-18 18:08:35 > 実際問題 non-const-container な v に v.begin() を取る時、 > 使われるのは begin() であって begin() const ではありません。 でも,iteratorはconst_iteratorに変換可能ですよね。 lib.container.requirementsのTable 65-Container requirementsの, X::iteratorのところに >convertible to X::const_iterator と書いてあります。 また,reverse_iteratorからconst_reverse_iteratorの間の変換についてですが……。 Table 66-Revsersible container requirementsによって, reverse_iteratorはreverse_iterator<iterator>であり, const_reverse_iteratorはreverse_iterator<const_iterator>です。 そして,lib.reverse.iteratorに >template <class U> reverse_iterator(const reverse_iterator<U>& u); という記述があります。 lib.reverse.iter.consによると,上記コンストラクタは, currentをu.currentで初期化する,とあります。 iteratorをconst_iteratorに変換できるということから, const_iteratorをiteratorで初期化することは可能です。 よって,const_reverse_iteratorはreverse_iteratorに変換可能です。 > たまたま VC++ の実装では forward-iterator は const と non-const とで比較互換、 > backward-iterator は const と non-const が比較非互換なだけのようです。 > # gcc-3.2.1 のもそういう実装でした。 こちらに関しては,標準化委員会に欠陥リポート等が上がっています。 http://std.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179 http://std.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#280 なので,次の版で比較可能になることでしょう。 FDISへのポインタ lib.container.requirements: http://www.kuzbass.ru:8086/docs/isocpp/lib-containers.html#lib.container.requirements lib.reverse.iterator: http://www.kuzbass.ru:8086/docs/isocpp/lib-iterators.html#lib.reverse.iterators lib.reverse.iter.cons: http://www.kuzbass.ru:8086/docs/isocpp/lib-iterators.html#lib.reverse.iter.cons Re[5]:const_reverse_iteratorでエラー #00001075 (Reply to #00001063) 名前 tetrapod 日時 2003-06-20 00:40:29 iterator から const-iterator へは変換可能でしたか (メモメモφm) # 逆は当然だめとして > よって,const_reverse_iteratorはreverse_iteratorに変換可能です。 本当に?逆ではなくて? std::const_reverse_iterator<T> cri; std::reverse_iterator<T> ri; ri=cri; が通っちゃうと、これだけで const はがしができちゃいますが。 >> template <class U> reverse_iterator(const reverse_iterator<U>& u); 仮引数が const_reverse_iterator<U>& で無いので異議有り。規格書が主張しているのは reverse_iterator のコピー生成ができるということかと。 ちょっとチェック STLport-4.5.3 で最初のソースをコンパイル。 おやおや = で代入できないと言ってますね。だめぢゃん > STLport まあ、規格書に処理系の実装が追いついていないのが C++ の現状ではあるので、 とりあえず今のところは const_reverse_iterator の使用は要注意、 ってとこでしょう。 Re[6]:const_reverse_iteratorでエラー #00001076 (Reply to #00001075) 名前 YuO (メール) 日時 2003-06-20 03:23:46 >> よって,const_reverse_iteratorはreverse_iteratorに変換可能です。 > 本当に?逆ではなくて? 逆です……書き間違い……。 #校正中に逆になったらしい。