私はUTF-8イテレーターアダプターに取り組んでいます。つまり、イテレータをaに、char
またはunsigned char
シーケンスをイテレータからシーケンスに変換するアダプタを意味しchar32_t
ます。ここでの私の仕事は、オンラインで見つけたこのイテレータに触発されました。
ただし、独自の実装を開始するときに標準を調べたところ、C ++がイテレータに課す要件に準拠しながら、このようなアダプタを実装することはできないようです。
たとえば、InputIterator要件を満たすUTF-8イテレータを作成できますか?はい。ただし、指定されたイテレータ自体がInputIteratorではない場合に限ります。どうして?
InputIteratorは、同じイテレータを複数回逆参照する機能を必要とするためです。それらがすべて等しい場合、そのイテレータの複数のコピーを逆参照することもできます。
もちろん、UTF-8イテレーターアダプターを逆参照するには、基本イテレーターの逆参照と、場合によっては増分を行う必要があります。そして、そのイテレーターがInputIteratorである場合、元の値をインクリメントした後に戻すことはできません。また、コピーが機能する必要があるという事実char32_t
は、以前にデコードされた値を表すをローカルに保存できないことを意味します。あなたはこれを行うことができたでしょう:
auto it = ...
auto it2 = it; //Copies an empty `char32_t`.
*it; //Accesses base iterator, storing `it.ch`.
*it; //Doesn't access the base iterator; simply returns `it.ch`.
*it2; //Cannot access `it.ch`, so must access base iterator.
わかりました。InputIteratorsは使用できません。しかし、ForwardIteratorはどうでしょうか?UTF-8文字シーケンスでForwardIteratorを適応できるForwardIteratorアダプターを作成することは可能ですか?
またはを生成するに*it
は操作が必要なため、これも問題です。InputIteratorsはに変換可能である何かを吐き出すことができますが、[forward.iterators] /1.3実際の参照を提供するために必要とされます。value_type&
const value_type&
value_type
ForwardIterator
X
が可変イテレータである場合、reference
はへの参照T
です。X
が定数イテレータの場合、reference
はへの参照ですconst T
ここでの唯一の手段は、そのようなすべてのイテレータがを持ち運ぶchar32_t
ことです。これは、その参照用のストレージを提供するためだけに存在します。その場合でも、イテレータインスタンスがインクリメントされ、逆参照されるたびに、その値を更新する必要があります。これは古い参照を事実上無効にし、標準はそれを明示的に許可していません(無効化はイテレータが破棄された場合、またはコンテナがそうした場合にのみ発生します)。
オンラインで見つけた前述のコードuint32_t
は、適切な参照ではなく値によって(C ++ 11より前に記述された)値を返すため、これが原因で無効です。
ここに頼ることはありますか?標準の何か、またはこれらの問題を回避するために使用できるいくつかの実装手法を見落としましたか?それとも、現在の標準の文言ではこれはまったく不可能ですか?
注:奇妙なことに、UTF-8変換用の準拠するOutputIteratorを記述できるように思われます。つまり、char32_t
UTF-8を受け取って、char
またはunsigned char
OutputIteratorに書き込む型です。
ForwardIterator
になったプロキシイテレータなど、あらゆる種類のプロキシイテレータとうまく適合しなかったことはよく知られていますvector<bool>
。その決定がなされた理由を説明するハーブサッターによって1999年に書かれた有名な記事がありました。現代では、この問題を再考する傾向がありました。エリックニーブラーが書いたものを見つけました。もっとあるかもしれません。いくつかのC ++提案では、ハーブサッター自身が書いたものもあるかもしれません。