私はこのコードを持っています:
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector <bool> v;
cin >> v[0];
return 0;
}
なぜ私はそれをすることができないのですか?コンパイラはそれをコンパイルしませんが、ベクトルに他の変数タイプがあり、問題なく動作します。これの何が問題なのですか?
これstd::vector<bool>
は、が特殊化であり、ベクトルのように機能しないためです。これは、規格の主要な欠陥であると広く認識されています。
メモリを節約するために、vector<bool>
各要素を1ビットとして格納します。ただし、ビットは個別にアドレス指定できないため、ビットに接続されoperator[]
た参照を返すことはできません。代わりに...をbool&
返し、これを処理するための関数のオーバーロードを提供しません。vector<bool>::reference
cin
(juanchopanzaは、ベクトルに要素ゼロがないことを正しく指摘しています。ただし、経由またはその他のメカニズムを使用した場合でも、参照を返さないresize
という事実が邪魔になります。)operator[]
を呼び出すv[0]
とき、ベクトルのサイズはゼロであるため、範囲外にアクセスしています。これは未定義の動作です。
さらに、それは個々の要素std::vector<bool>
を保持していないという事実のために奇妙な振る舞いをする専門です。bool
それoperator[]
は一種のプロキシオブジェクトを返します、その演算子への呼び出しはあなたが期待することをしないかもしれません。注意して使用するか、まったく使用しないでください。
この作業例(ここにある同様のライブデモ)のように、値をローカル変数に読み込んでから、それをベクトルの後ろにプッシュすることで、問題を解決できます。
#include <vector>
#include <iostream>
int main()
{
std::vector<bool> v;
std::cout << std::boolalpha;
v.push_back(true);
std::cout << v[0] << std::endl;
bool b;
cin >> b;
v[0] = b;
std::cout << v[0] << std::endl;
}
これは機能するはずです:
#include <iomanip>
...
bool a;
cin >> boolalpha >> a;
v.push_back(a);
bool
(Ben Voigtによって言及された問題に加えて、現在のコードは、アクセスしているときにベクトルが空であるという理由以外のタイプでは安全ではありませんv[0]
。)