2

a を反復処理するとvector<bool>、反復子によって逆参照された要素が const であるかのように認識されることがわかります。何故ですか?コンテナーまたは要素の型 (list<bool>またはなど) を変更vector<short>し、要素が非 const である。このコードは、私が話していることを示しています。

typedef bool T;
#define C vector
istringstream &operator>>(istringstream &iss, T &v)
{
    cout << "non-const" << endl;
    return iss;
}

istringstream &operator>>(istringstream &iss, const T &v)
{
    cout << "const" << endl;
    return iss;
}

istringstream &operator>>(istringstream &iss, C<T> &c)
{
    for (C<T>::iterator it = c.begin(); it != c.end(); ++it)
    {
        iss >> *it;
    }
    return iss;
}

int main()
{
    C<T> c(1);
    istringstream iss("1");
    iss >> c;
}

の場合vector<bool>、このプログラムは「const」をコンソールに表示します。上部の typedef と manifest 定数をこれら 2 つの組み合わせ以外に変更すると、「non-const」と出力されます。また、行を , に置き換えるiss >> *itT v; iss >> v; *it = v;、期待どおりに機能します。すべての組み合わせが「非定数」と出力されます。

GCC 4.1.2 C++98 (codepad.org 経由) および VS2015 C++14+ (?) でも同じ動作が見られます。

4

3 に答える 3

6

名前にもかかわらず、 svector<bool>は含まれておらずbool、その反復子を逆参照してもbool&. 代わりに、可能な限りvector<bool>::referenceの動作を模倣しようとするtype のオブジェクトを提供します。bool&

vector<bool>::referenceaを aに変換する方法がないbool&ため、非 const オーバーロードは機能しません。vector<bool>::referenceただし、 に変換してbool、 にバインドできconst bool&ます。

于 2015-06-21T00:13:21.423 に答える
5

メモリを節約するために、vector<bool>は の実際の配列ではありませんbool。bool 値は 1 ビットだけ格納する必要がありますが、可能な最小サイズは 1 バイト = 8 ビットです。したがって、単純な実装を使用しないことで、bool の単純な配列が提供するものよりも 8 倍効率的なストレージ (メモリに関する限り) を持つことができます。

ただし、結果として、 a の要素はvector<bool>bool ではなく、 avector<bool>::referenceとほとんど同じではありませんが、 a になりbool&ます。ほとんどの操作はここにありますが、そうでないものもあります (|=たとえば)

それでも、それを に変換するか、それを使用してbool新しいオブジェクトを初期化const boolできます...そして、この新しいオブジェクトで何をしてもかまいません

于 2015-06-21T00:17:48.287 に答える
2

std::vector<bool>は、std::vectorスペース効率の高い動的ビットセットとして機能する の特殊化です。ブール値を表すプロキシ クラス型のオブジェクトから返されbegin()、実際にポイントするイテレータ。end()

イテレータの逆参照から返される参照は、実際のブール値ではなく、クラス タイプの prvalue です。型の prvalue に変換されるboolため、const への参照を取得するオーバーロードが優先されます (rvalue は const への参照にバインドできます)。

于 2015-06-21T00:13:46.993 に答える