適合するプログラムによって検出可能であり、従って不適合であるこの拡張の動機は、参照 (const およびその他) に関してvector<bool>
より似た動作をさせることです。vector<char>
序章
1998年以来、vector<bool>
「コンテナではない」と揶揄されてきました。 最初の LWG の問題の 1 つであるLWG 96が議論を開始しました。17年後の今日、vector<bool>
ほとんど変わっていません。
このホワイト ペーパーでは、 の動作が のvector<bool>
他のすべてのインスタンス化とどのように異なるかについて、具体的な例をいくつか説明しvector
ます。vector<bool>
ただし、同じ論文では、適切に実装された場合に非常に優れたパフォーマンス プロパティが得られることについて詳しく説明しています。
まとめ: vector<bool>
悪い容器ではありません。それは実際には非常に便利です。名前が悪いだけです。
戻るconst_reference
上記で紹介し、ここで詳しく説明しvector<bool>
たように、一般的なコードでは他のvector
インスタンス化とは異なる動作をすることが悪い点です。具体的な例を次に示します。
#include <cassert>
#include <vector>
template <class T>
void
test(std::vector<T>& v)
{
using const_ref = typename std::vector<T>::const_reference;
const std::vector<T>& cv = v;
const_ref cr = cv[0];
assert(cr == cv[0]);
v[0] = 1;
assert(true == cv[0]);
assert(cr == cv[0]); // Fires!
}
int
main()
{
std::vector<char> vc(1);
test(vc);
std::vector<bool> vb(1);
test(vb);
}
標準仕様では、マークされたアサート// Fires!
がトリガーされるとされtest
ていますが、vector<bool>
. a vector<char>
(または適切な非デフォルトが割り当てられている場合はそれvector
以外) で実行すると、テストに合格します。bool
T
vector<bool>
libc++ の実装では、一般的なコードで異なる動作をすることによる悪影響を最小限に抑えようとしました。これを達成するために行ったことの 1 つは 、指定された と同じようにproxy-referencevector<T>::const_reference
を作成することですが、それを介して代入することはできません。つまり、libc++ では、本質的には、そのビットのコピーではなく、内のビットへのポインターです。vector<T>::reference
vector<T>::const_reference
vector
libc++ では、上記は と の両方にtest
渡されます。vector<char>
vector<bool>
どのくらいの費用で?
欠点は、質問に示されているように、この拡張子が検出可能であることです。ただし、このエイリアスの正確なタイプを実際に気にするプログラムはほとんどなく、より多くのプログラムが動作を気にします。
この不適合の動機は何ですか?
ジェネリック コードで libc++ クライアントの動作を改善するには、十分なフィールド テストを行った後、C++ 業界全体の改善のために、この拡張機能を将来の C++ 標準に提案します。
このような提案は、bit_vector
現在の とほぼ同じ API を持つ新しいコンテナ (例: )の形で提供される可能性がありますが、ここvector<bool>
で説明するようないくつかのアップグレードが含まれていconst_reference
ます。vector<bool>
専門 化の非推奨 (および最終的な削除) が続きます。addや一連のイテレータなど、bitset
この部門で少しアップグレードすることもできます。const_reference
つまり、後から考えるとbitset
to は to (名前を-- などvector<bool>
に変更する必要があります) であり、そのままtoです。そして、とについて話しているかどうかにかかわらず、類推は当てはまるはずです。bit_vector
array
vector
bool
value_type
vector
array
libc++ の拡張機能として開始された C++11 および C++14 機能の例が複数あります。これが、標準が進化する方法です。実際に実証された 積極的な現場経験は、強い影響力を持っています。標準化を支持する人々は、既存の仕様の変更に関しては保守的です (そうあるべきです)。推測が正しいと確信している場合でも、推測することは、国際的に認められた標準を発展させるための危険な戦略です。