12

簡単に言えば、私は持っています

#include <vector>

template <class T>
class wrapped_vector {
private:
        std::vector<T> elements;
public:
        wrapped_vector() {
                elements.resize(20);
        }

        T& operator[](int i) {
                return elements[i];
        }

        const T& operator[](int i) const {
                return elements[i];
        }
};

int main(void) {
        wrapped_vector<int> test_int;
        test_int[0] = 1;

        wrapped_vector<bool> test_bool;
        test_bool[0] = true; // remove this line and it all compiles
}

そしてそれは私にコンパイルエラーを与えます

test.cpp: In instantiation of ‘T& wrapped_vector<T>::operator[](int) [with T = bool]’:
test.cpp:28:13:   required from here
test.cpp:15:34: error: invalid initialization of non-const reference of type ‘bool&’ from an rvalue of type ‘std::vector<bool, std::allocator<bool> >::reference {aka std::_Bit_reference}’
4

1 に答える 1

24

あなたは「魔法」のまた別の副作用に噛まれましたstd::vector<bool>

std::vector<bool>実際には s の連続した配列を格納するのではなく、それらをビットセットとしてパックするためbool、ビットセットの中央にあるビットへの「実際の」参照を返すことはできません (ビットは直接アドレス指定できないため)。このため、そのをオーバーロードして参照セマンティックを「偽造」operator[]するプロキシ オブジェクトを返します。operator=

ここに問題があります。このプロキシ オブジェクトは ではないためbool &、メソッドでそのまま返すことはできません。

解決する最も簡単な方法は、次のようなものです。

    typename std::vector<T>::reference operator[](int i) {
            return elements[i];
    }

    typename std::vector<T>::const_reference operator[](int i) const {
            return elements[i];
    }

これにより、そのメソッドで「へのstd::vector参照」として使用される型を実際に返すことが保証されます。T

また、std::vector<T>::size_typeインデックスに使用することもできます (主にフォワーダー関数の一貫性のため)。

于 2013-01-29T22:55:01.293 に答える