1. ホーム
  2. c++

[解決済み] なぜvector<bool>はSTLコンテナではないのですか?

2022-08-05 05:55:25

質問

Scott Meyersの書籍の18番目の項目 Effective STL: 標準テンプレートライブラリの使い方を改善する50の具体的な方法 には、以下を避けるように書かれています。 vector <bool> はSTLコンテナではないので避けるようにと書かれています。 bool s.

次のようなコードです。

vector <bool> v; 
bool *pb =&v[0];

はSTLコンテナの要件に違反し、コンパイルされません。

エラーになります。

cannot convert 'std::vector<bool>::reference* {aka std::_Bit_reference*}' to 'bool*' in initialization

vector<T>::operator [] 戻り値の型は T& のはずですが、なぜか特殊なケースで vector<bool> ?

とは何ですか? vector<bool> は本当に構成されているのでしょうか?

アイテムはさらにこう言っている。

deque<bool> v; // is a STL container and it really contains bools

の代わりとして使えるか? vector<bool> ?

どなたか解説をお願いします。

どのように解決するのですか?

スペースの最適化のため、C++ 標準では (C++98 まで) 明示的に vector<bool> を特別な標準コンテナーとして明示的に呼び出しており、各ブールは通常のブールのように 1 バイトではなく、1 ビットだけのスペースを使用します (一種の "dynamic bitset" を実装しています)。この最適化と引き換えに、通常の標準コンテナのすべての機能とインターフェイスを提供するわけではありません。

この場合、バイト内のビットのアドレスを取ることができないので、次のようなものがあります。 operator[] を返すことはできません。 bool& を返すのではなく、問題のある特定のビットを操作することができる プロキシオブジェクトを返します。このプロキシオブジェクトは bool& ではありませんので、そのアドレスを bool* にアドレスを割り当てることができません。これは、順番に、以下のことを意味します。 bool *pb =&v[0]; は有効なコードではないことを意味します。

一方 deque はそのような特殊化を呼び出していないので、各boolはバイトを取り、そこから返される値のアドレスを取ることができます。 operator[] .

最後に、MS 標準ライブラリの実装は、deque に小さなチャンクサイズを使用するという点で(間違いなく)最適でないことに注意してください。