Подтвердить что ты не робот

С С++, как я могу обернуть вектор и перегрузить [] для всех типов?

Короче говоря, у меня

#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}’
4b9b3361

Ответ 1

Вас укусил еще один побочный эффект "волшебства" std::vector<bool>.

Так как std::vector<bool> фактически не сохраняет смежный массив bool s, но упаковывает их как битовый набор, он не может вернуть "реальную" ссылку на бит в середине битового набора (поскольку бит aren ' t непосредственно адресуемый); по этой причине его 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 для индексов (в основном для согласованности ваших функций пересылки, чем что-либо еще).