value_type がコンテナーに直接格納されていない適合コンテナーを作成することは不可能であるという結論に多かれ少なかれ到達しました。値の型が部分的に計算されているか、不連続な部分から組み立てられているコンテナがあればいいのにと思うことがよくあるので、これは残念だと思います(以下の例ですが、質問には直接関係ありません)。プロキシ オブジェクトを使用するイテレータの書き方は知っていますが、かなり面倒です。しかし、私は今、C++ 標準にそのような野獣のための余地があるかどうか疑問に思っています。ここにはおそらく言い回しが多すぎます。tl;dr バージョンは単純です: §24.2.5 のパラグラフ 1 と 6 は実際には何を意味するのでしょうか? また、明白な意味に違反すると、標準アルゴリズムがどの程度破られるのでしょうか? 別の言い方をすれば、プロキシ イテレータを許可するように解釈するにはどうすればよいでしょうか。
Pete Becker が指摘するように、標準ライブラリ コンテナーに設定された要件にコンテナーが準拠することを強制するものは実際には何もありません。しかし、コンテナを多くの標準アルゴリズムで使用するためには、少なくとも a の適合するイテレータを持たなければならないか、それforward_iterator_tag
について嘘をついても、特定のアルゴリズムがそのイテレータに課す運用上の (正式ではないにしても) 要件を満たすことができる必要があります。 .
これが私の推論です:
表 96 (§ 23.2.1)、コンテナー要件には、以下が含まれます。
Expression Return type Assertion/note
------------ ------------- ---------------------
X::iterator iterator type any iterator category
whose value that meets the
type is T forward iterator
requirements.
Convertible to
const_iterator.
a.begin() iterator;
const_iterator for
constant a.
さて、フォワードイテレータ:
§ 24.2.5、パラ。1:
クラスまたはポインター型
X
は、次の場合に前方反復子の要件を満たします。—
X
可変イテレータの場合reference
、 への参照T
です。ifX
は const イテレータでreference
、への参照ですconst T
*a
直接返す必要がないのは事実ですreference
(ここa
で は type ですX
)。要件は次のとおりです。
from Table 107 (入力イテレータ)が参照解除可能である
*a
場合、「T に変換可能」でなければなりませんa
。表 106 から (イテレータ)
*r
は型を持たなければならずreference
、ここでr
は型でX&
あり、参照解除可能です。
ただし、表 106 では、 が を++r
返すことも指定されているX&
ため、 である*++r
必要がありますreference
。また、(表 107 に従って) である*a++
必要がありますがreference
、(表 109)a[n]
は「参照に変換可能」である必要があるだけです。*a
where a
is of typeX
と*r
where r
is of typeがどのように異なるかはわかりませんX&
が、微妙な点が欠けている可能性があります。
ここには多少の余裕があるかもしれませんが、それほど多くはありません。ある時点で、T
実際にコンテナーに がない場合は、それへの参照を提供できるように を作成する準備をする必要があります。
しかしキッカーは
§ 24.2.5、パラ。6 (
a
とb
は type の値X
):a
とb
が両方とも逆参照可能である場合、 とが同じオブジェクトにバインドされているa == b
場合に限ります。*a
*b
の正式な定義は見つかりませんbound to
が、アドレス指定できないオブジェクトのイテレータを作成するための通常の戦略は、プロキシ オブジェクトを作成することであり、通常はイテレータ自体の内部に格納されるようです。この場合、たとえそれらが論理的に同じ位置を示していたとしても、2 つの異なる反復子オブジェクト間で成功する等価比較を禁止する以外の方法で 24.2.5/6 を解釈するには、「バインド先」が何を意味するのかについて非常に寛大な理解が必要です。コンテナで。
一方、知っておくべきディートマー・キュールは、この質問への回答で次のように述べています。
C++ 2011 では要件が緩和され、イテレータは必ずしも左辺値を生成する必要はありません
では、イテレータはプロキシを返すことができますか? 可能であれば、そのようなプロキシの性質は何ですか? そのようなイテレータが非準拠であるという私の推論はどこで失敗しますか?
約束どおり、有効な value_types がコンテナーに連続して格納されないいくつかのコンテナー:
1) キーと値の型を 2 つの個別のベクトルに効率的に格納できるコンパクトな連想コンテナー。(キーをベクトルに保持すると、割り当てのオーバーヘッドを削減するだけでなく、キャッシュの使いやすさも向上します。)
2)vector<T>
として偽装し、map<integer_type, T>
他の型との相互運用性を簡素化するmap<X, T>
。
tuple
3) いくつかの他のコンテナーを圧縮することによって形成される論理コンテナーであり、圧縮されたコンテナーの値の型への参照である論理 value_type を生成します。(一部のアプリケーションでは、圧縮されたコンテナーの 1 つ以上が、他の値の関数として、またはシーケンス番号として完全に計算される場合があります。)
4) 一部の値のみを持つ集約タイプのコンテナーのビュー。(おそらく、基になるコンテナーとビューの両方がタプルであり、ビューのタプルの型リストは、基になるコンテナーの型の、おそらく異なる順序のサブセットです)。
他の人がこのリストに簡単に追加できると確信しています。これらは、私が過去数か月の間に何らかの方法でハッキングしたものにすぎません。