web-dev-qa-db-ja.com

連続イテレータ検出

C++ 17では、ContiguousIteratorの概念が導入されました http://en.cppreference.com/w/cpp/iterator 。ただし、_contiguous_iterator_tag_によって報告される_random_access_iterator_tag_(現在は_std::iterator_traits<It>::iterator_category_があるのと同じ方法)を計画しているようには見えません。

_contiguous_iterator_tag_が欠落しているのはなぜですか?

イテレータが連続しているかどうかを判断するための従来のプロトコルはありますか?またはコンパイル時のテスト?

過去に、コンテナの場合 _::value_タイプへのポインタに変換する.data()メンバーがあり、.size()メンバーがある場合ポインターの違いに変換できる場合、コンテナーが隣接していると想定する必要がありますが、イテレーターの類似の機能を引き出すことはできません。

1つの解決策は、連続するイテレータ用のdata関数も持つことです。

もちろん、連続概念は、すべてのnに対して&(it[n]) == (&(*it)) + nの場合に機能しますが、これはコンパイル時にチェックできません。


[〜#〜] edit [〜#〜]:これをC++の概念のより広い文脈に置くこのビデオを見つけました。 CppCon 2016:「現代のマルチコア世界におけるイテレータ階層の構築と拡張」 PatrickNiedzielski著。このソリューションは概念(Lite)を使用しますが、最終的には、連続するイテレーターは_pointer_from_関数(私のdata(...)関数と同じ)を実装する必要があるという考えです。

結論として、概念は理論の形式化に役立ちますが、誰かが、隣接するイテレータに対して新しい特別な名前の関数をどこかで定義するという意味で、魔法ではありません。話はセグメント化されたイテレータ(対応する関数segmentlocal)に一般化されますが、残念ながら、ストライドポインタについては何も述べていません。

27
alfC

理論的根拠は N4284 に示されています。これは、隣接するイテレータ提案の採用バージョンです。

この論文では、ランダムアクセスイテレータの改良版として「連続イテレータ」という用語を紹介しますが、Nevin Liberの論文N3884「連続イテレータ:ランダムアクセスイテレータの改良」のIssaquahの議論中にコードを壊すことが判明した対応するcontiguous_iterator_tagを紹介しません。 。

std::random_access_iteratorを改良できないと想定し、それに対して明示的なチェックを行ったため、一部のコードが壊れていました。基本的に、イテレータのカテゴリをチェックするためにポリモーフィズムに依存しない悪いコードを壊しましたが、それでもコードを壊したので、contiguous_iterator_tagは提案から削除されました。

また、std::reverse_iteratorのようなクラスには、追加の問題がありました。逆に連続したイテレーターを連続したイテレーターにすることはできませんが、通常のランダムアクセスイテレーターにすることができます。この問題はstd::reverse_iteratorで解決できた可能性がありますが、イテレーターカテゴリのコピー中にイテレーターを拡張するユーザー定義のイテレーターラッパーが増えると、嘘をつくか、正しく機能しなくなります(たとえば、ブーストイテレーターアダプター)。


上記の私の最初の答え以来、std::contiguous_iterator_tagはRangesTSに戻され、C++ 20に存在するようになります。 std::iterator_traits<T>::iterator_categoryではなく、std::iterator_traits<T>::iterator_conceptを介して提供することで上記の問題を回避し、既存のコードを壊します。

概念ContiguousIteratorおよびContiguousRange。それらは現在、主にRandomAccessの対応物とは異なり、iterator_conceptをチェックして、それがランダムアクセスであるか連続イテレータであるかを認識します。ただし、別の提案 ContiguousIterator の有用なポインタは、連続するイテレータがto_address関数を実装することも提案しています。基になるポインタ。この提案が受け入れられる軌道に乗っているかどうかはわかりません。

18
Morwenn