ビットの動的配列を格納する必要があります。
vector<bool>のC++リファレンスページには、次の情報があります。
ストレージは必ずしも
bool
値の配列である必要はありませんが、ライブラリの実装により、各値が1ビットに格納されるようにストレージが最適化される場合があります。
vector<bool>
を使用するプログラムが実際にブール値(バイト)ではなくベクトルにビットを格納することを確認するにはどうすればよいですか?
そうしようとしないでください。代わりに、boost::dynamic_bitset
実際に必要なものを明確に示す which を使用してください。最適化は、実際にはバグの可能性を数多く生み出します。vector<bool>
たとえば、反復子を使用する場合です (通常はプロキシ オブジェクトを返すため)。
そうですね、コンパイラに付属のヘッダー ファイルはいつでも調べることができます。STL コンテナーはほぼ完全にテンプレート クラスであるため、実装のすべてではないにしてもほとんどの部分がヘッダーに表示されます。
デバッガーでオブジェクトを調べるvector
ことも役立つ場合があります。
vector<bool>
注:一方、 は C++ コミュニティからかなり嫌われていることに注意してください。また、この最適化はサイズのためであり、速度のためではないことに注意してください。
https://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=98
コンパイル時にこれを確認するには、次の非定数バージョンの戻り型を確認しvector<bool>::operator[]
ます。値をビットとして格納する実装は、ではなくプロキシ参照クラスを返す必要がありbool&
ます。
ここでチェックすることは本当に何もありません。vector<bool>
より大きなオブジェクトの代わりにビットを格納するための特殊化は、標準で必要とされています。§23.2.5: 「スペース割り当てを最適化するために、bool 要素用の vector の特殊化が提供されています:」.
ある観点から、あなたが引用したことは少なくともある程度正しいと思います。基本的に、コンパイラの適合性を証明する人は誰もおらず、すべての適合要件を満たそうとするコンパイラも本質的に存在しないため、コンパイラはこの要件を無視することもできます。
私はそれを行うコンパイラを知りません - もし誰かがそうしたなら、それはおそらくかなりよく知られていると思います. 専門化を削除することについてかなり激しい議論が時々vector<bool>
あったので、誰かが実際の例を持っていれば、それがどれだけ良くなったか(または悪くなったか)、それについて聞いたことがあると思います.
編集: C++11 では、要件はstd::vector<bool>
§23.3.7 に移動されました。bool
さらに重要なことは、値の連続した割り当てではなく、それぞれが単一のビットとして格納されるパックされた表現bool
が現在推奨事項にすぎないことを指定するために、表現が変更されたことです。
少なくとも IMO では、これは実際の違いはほとんどありません。私の知る限り、すべての実際の実装はまだパック表現を使用しているため、パック ストレージは理論的には保証されていませんが、実際にはとにかく発生します。
このプログラムはそれを証明しています。
#include <vector>
#include <iostream>
template <typename T>
void showSize() {
std::vector<T> myvec;
size_t capacity = myvec.capacity();
std::cout << "capacity: " << myvec.capacity() << std::endl;
std::cout << "size: " << myvec.size() << std::endl;
while (myvec.capacity() < 1024) {
while (myvec.capacity() == capacity) {
myvec.push_back(T());
}
capacity = myvec.capacity();
std::cout << "capacity: " << myvec.capacity() << std::endl;
std::cout << "size: " << myvec.size() << std::endl;
}
}
int main(int, char**) {
std::cout << std::endl << std::endl;
std::cout << "*********************" << std::endl << std::endl;
std::cout << "Booleans: " << std::endl << std::endl;
showSize<bool>();
std::cout << std::endl << std::endl;
std::cout << "*********************" << std::endl << std::endl;
std::cout << "Chars: " << std::endl << std::endl;
showSize<char>();
}
出力:
*********************
Booleans:
capacity: 0
size: 0
capacity: 64
size: 1
capacity: 128
size: 65
capacity: 256
size: 129
capacity: 512
size: 257
capacity: 1024
size: 513
*********************
Chars:
capacity: 0
size: 0
capacity: 1
size: 1
capacity: 2
size: 2
capacity: 4
size: 3
capacity: 8
size: 5
capacity: 16
size: 9
capacity: 32
size: 17
capacity: 64
size: 33
capacity: 128
size: 65
capacity: 256
size: 129
capacity: 512
size: 257
capacity: 1024
size: 513
したがって、キーは、bools の容量が一度に 64 エントリ増加することです (int または私のマシンのサイズ)。これは、一度に 8 バイトしか予約していないことを示唆しています。
hugevector<bool>
を作成し、プログラムのメモリ使用量を調べます。
vector
または、単にソース コードを確認してください。ヘッダーをのぞくことができます。