28

の仕様を調べていて、 typedef がC++03 からC++11 に変更されstd::vectorていることに気付きました。びっくりしたので、もっと深く調べてみました。referenceAllocator::referencevalue_type&

C++03 §20.1.5 [lib.allocator.requirements] には、 であると定義され、 であると定義されているテーブル 32がX::referenceあります。T&X::const_referenceT const&

ただし、C++11 §17.6.3.5 [allocator.requirements] には、referenceconst_referenceが欠落しているテーブル 28 があります。

std::allocator_traits次に、 を含まない C++11 に§20.6.8 を追加しましたreference。しかし、§20.6.9std::allocatorはそうです。

最後に、§23.2.1 [container.requirements.general] があり、「の左辺値」および「の定数左辺値」であると定義X::referenceされてTX::const_referenceますT

それで、私はグーグルで検索して、アロケーター要件からの削除を提案するこの論文( 12reference )を見つけましたが、その背後にある理論的根拠については言及していません。しかし、変更に反対するLWG の問題もあります。

また、マシン固有のメモリ レイアウトをカプセル化する方法について語っている Alexander Stepanov とのインタビューと、コンテナー要素へのポインターの取得、コンテナーの要件、コンテナーではない方法について語っているHerb Sutter の投稿を見つけました。referencestd::vector<bool>

それで、あなたはこれらすべてについてどう思いますか?役に立ちましたかreference、それは目的を果たしましたか? 「派手な」参照は標準にどのように適合しますか? これは、それらを完全に排除し、より厳格なコンテナー要件を作成し、廃止するという大胆な動きstd::vector<bool>ですか?

4

3 に答える 3

5

http://en.wikipedia.org/wiki/Allocator_(C%2B%2B)

「これらはもともと、ライブラリをより柔軟にし、基礎となるメモリ モデルから独立させ、プログラマがライブラリでカスタム ポインタと参照型を利用できるようにする手段として意図されていました。しかし、STL を C++ 標準に採用する過程で、C++標準化委員会は, メモリモデルの完全な抽象化が容認できないほどの性能低下を招くことを認識した. これを改善するために, アロケータの要件はより制限された. その結果, アロケータによって提供されるカスタマイズのレベルは, Stepanov によって最初に想定されたよりも制限されている. ."

もともと、それらはメモリ自体を抽象化するように設計されており、たとえば、インターネット接続を介して別のマシンにメモリを割り当て、ポインタ/参照を使用してデータを前後にコピーして、何が生きているかを追跡できます。同様に、純粋な C++ で Java のような GC を作成することもできます。この抽象化は素晴らしいアイデアのように思えました。

ただし、これにより、当時は許容できないと見なされていたパフォーマンスのペナルティが発生しました。また、考えてみれば、コードで作業することはほぼ不可能です。Everyvoid func(const string&)template<class allocator> void func(allocator::reference)、推定不可能なコンテキストである にする必要があるため、関数呼び出し ( func<std::allocator<std::string>::const_reference>(username)) にアロケータを明示的に記述する必要があります。現在、アロケーターは単にメモリの割り当て/解放を抽象化しています。

于 2014-01-09T17:29:55.780 に答える
2

Alexander Stepanov とのインタビューで、 STLを標準ライブラリに追加する提案の際に、メモリ モデルから抽象化を作成するように依頼されたと述べています。したがって、アロケータが生まれました。LWGの問題には、referenceカスタム アロケータが と定義されている実装の例がありますT __far&

しかし、検索する時間があまりないため理由は不明ですが、C++03 標準の §20.1.5 p4 には次のテキストがあります。

この国際規格で説明されているコンテナの実装は、そのアロケータ テンプレート パラメータが、表 32 の要件に加えて、次の 2 つの追加要件を満たしていると想定することが許可されています。

— 特定のアロケータ型のすべてのインスタンスは交換可能である必要があり、常に互いに同等である必要があります。

— typedef メンバーの pointer、const_pointer、size_type、および difference_type は、それぞれ T*、T const*、size_t、および ptrdiff_t である必要があります。

これにより、カスタム メモリ モデル アロケーターが標準コンテナーと相互運用する機能が効果的に無効になります。

「アロケータ」という単語に言及しているすべての C++11 以前の論文を検索しているときに、これらの単語を標準から削除するという主要なコンセンサスを見つけました。最後に、この論文では、次の注釈を付けてそれらを削除することを提案しています。

イタチの言葉はなくなった。グラスを上げて乾杯しましょう。

勝利?ついにメモリ モデルを使いこなせるようになるのでしょうか? いいえ、そうではありません。とりわけ、同じ論文はreference、アロケータ要件から削除することを提案しています。そして、それは標準に投票されたようです.

先に述べたLWG の問題は変更に反対していますが、次の声明でクローズされました。

変更することにコンセンサスがない

したがって、アロケーターの本来の目的は、今日ではそれほど重要ではないようです。ウィキペディアには次のように書かれています。

アロケーターの現在の目的は、基礎となるハードウェアのアドレス モデルを適応させることではなく、プログラマーがコンテナー内のメモリ割り当てを制御できるようにすることです。実際、改訂された標準では、C++ アドレス モデルの拡張機能を表すアロケータの機能が削除され、正式に (そして意図的に) アロケータの本来の目的が削除されました。

最後に、Container::referenceアロケーターとは何の関係もありません。実際にはコンテナではないプロキシされたコレクションを可能にするために作成されました。だからここにとどまります。ところで、これは標準の最後の言葉がいかに当初の意図に反するかの別の例のようです。

于 2013-05-03T15:37:14.303 に答える