C++ Operatore di sottoscrizione di matrice


Esempio

È anche possibile sovraccaricare l'operatore di indice [] .

Dovresti sempre (il 99,98% delle volte) implementare 2 versioni, una versione const e una not const , perché se l'oggetto è const , non dovrebbe essere in grado di modificare l'oggetto restituito da [] .

Gli argomenti vengono passati da const& anziché da valore perché il passaggio per riferimento è più rapido che per valore e const modo che l'operatore non cambi accidentalmente l'indice.

Gli operatori restituiscono per riferimento, poiché per impostazione è possibile modificare l'oggetto [] return, ovvero:

std::vector<int> v{ 1 };
v[0] = 2; //Changes value of 1 to 2
          //wouldn't be possible if not returned by reference

Puoi sovraccaricare solo all'interno di una class / struct :

//I is the index type, normally an int
T& operator[](const I& index)
{
    //Do something
    //return something
}

//I is the index type, normally an int
const T& operator[](const I& index) const
{
    //Do something
    //return something
}

Gli operatori di pedici multipli, [][]... , possono essere raggiunti tramite oggetti proxy. Il seguente esempio di una semplice classe matrice matrice principale lo dimostra:

template<class T>
class matrix {
    // class enabling [][] overload to access matrix elements
    template <class C>
    class proxy_row_vector {
        using reference = decltype(std::declval<C>()[0]);
        using const_reference = decltype(std::declval<C const>()[0]);
    public:
        proxy_row_vector(C& _vec, std::size_t _r_ind, std::size_t _cols)
            : vec(_vec), row_index(_r_ind), cols(_cols) {}
        const_reference operator[](std::size_t _col_index) const {
            return vec[row_index*cols + _col_index];
        }
        reference operator[](std::size_t _col_index) {
            return vec[row_index*cols + _col_index];
        }
    private:
        C& vec;
        std::size_t row_index; // row index to access
        std::size_t cols; // number of columns in matrix
    };

    using const_proxy = proxy_row_vector<const std::vector<T>>;
    using proxy = proxy_row_vector<std::vector<T>>;
public:
    matrix() : mtx(), rows(0), cols(0) {}
    matrix(std::size_t _rows, std::size_t _cols)
        : mtx(_rows*_cols), rows(_rows), cols(_cols) {}

    // call operator[] followed by another [] call to access matrix elements
    const_proxy operator[](std::size_t _row_index) const {
        return const_proxy(mtx, _row_index, cols);
    }

    proxy operator[](std::size_t _row_index) {
        return proxy(mtx, _row_index, cols);
    }
private:
    std::vector<T> mtx;
    std::size_t rows;
    std::size_t cols;
};