-2

重複の可能性:
vector<bould> 内の要素のアドレスにアクセスしているときに一時的なアドレスを取得する

次のコードの7行目で「一時的なアドレスを取得しています」という警告が表示されます

vector<bool> boolVect;
bool x = true;
boolVect.push_back(true);
boolVect.push_back(false);
ofstream fMetaOut("tmp.txt", ios::out);
fMetaOut.write((char* )&x, sizeof(bool));
fMetaOut.write((char* )&boolVect[0], sizeof(bool));
fMetaOut.close();

この警告が 6 行目ではなく 7 行目に表示されるのはなぜですか?? どちらもブール アドレスを使用します。
どうすればこの警告を取り除くことができますか?

4

2 に答える 2

6

xは一時変数ではなく、左辺値であり、スタックに常駐する自動変数です。
一方、&boolVect[0]左辺値ではありません。
l-value は、アドレスを取得できるエンティティです。つまり、名前でアドレス指定できるように、メモリ内に存在するのに十分な長さの寿命を持つ変数です。

何が問題ですvector<bool>か?? それはうまくいきますvector<int>

C++ 標準ライブラリは、ブール型の vector の特殊化を提供します。目標は最適化であり、通常の vector の type 実装よりも小さいサイズを使用しますbool。の通常の実装では、各要素に対してbool少なくとも1バイトが予約されます。vector<bool>特殊化は通常、要素に対して内部的にのみビットを使用するため1、通常は 8 分の 1 になります。ただし、この最適化には代償が伴います
。C++ では、アドレス指定可能な最小値のサイズは少なくとも1バイトである必要があります。したがって、このようなベクトルの特殊化には、参照と反復子の特別な処理が必要です。その結果、 avector<bool>は他のベクトルのすべての要件を満たしていません。表示される動作はその一例であり、 の要素はvector<bool>真の左辺値ではありません。

于 2012-05-10T05:13:33.877 に答える
2

の他の特殊化とは異なりvector、はオブジェクトvector<bool>の配列を管理しません。bool代わりに、パックされたビットフィールドを管理します。

ビットは個別にアドレス指定boolVect[0]できないため、 への参照ではありませんbool。に変換可能な型の (一時的な) オブジェクトですbool。ベクトル要素への参照またはポインターを取得する方法はありません。

参照できるブール値フラグのコンテナが必要な場合は、vector<char>またはdeque<bool>が適切な選択かもしれません。

x(一時的ではない)boolオブジェクトであるため、 のアドレスを取得しても問題ありません。

于 2012-05-10T05:23:50.970 に答える