С++ выборочно перегружает []?

Данный:

class example
{
    public:
        std::vector<std::vector<int>> a;
        int b;
}

func()
{
    example e;
    ... // populate e

Затем я мог бы использовать примеры таких членов.

    int n = e.b;
    int n2 = e.a[2][3];

Однако могу ли я альтернативно переопределить оператор [ ] таким образом, чтобы.

    int n = e.b;
    int n2 = e[2][3];
}

?

edit: Извините, пример теперь исправлен.


person alan2here    schedule 29.03.2012    source источник
comment
Я не вижу [] в вашем коде...   -  person Kerrek SB    schedule 30.03.2012
comment
Где вам нужна перегрузка? Я не вижу необходимости в [].   -  person Hauleth    schedule 30.03.2012
comment
Должен ли этот последний блок каким-то образом отличаться?   -  person Michael Wilson    schedule 30.03.2012
comment
@MichaelWilson, да, ему не хватает .a.   -  person Mr Lister    schedule 30.03.2012
comment
Это может помочь: stackoverflow.com/a/1971207/14065   -  person Martin York    schedule 30.03.2012
comment
Я не уверен, за что проголосовали против. Кажется, правильный вопрос.   -  person Martin York    schedule 30.03.2012
comment
@Loki: отрицательные голоса, вероятно, были предварительно отредактированы, когда вопрос не имел отношения к operator[].   -  person ildjarn    schedule 30.03.2012
comment
-1 за резкое изменение вопроса. @LokiAstari смотрите историю изменений.   -  person Luchian Grigore    schedule 30.03.2012
comment
Извините, я отстойно отношусь к редактированию, особенно к человеку, который только что ответил, хотя это вопрос, который я хотел задать :¬P, и на него есть отличный ответ от Кристиана Рау.   -  person alan2here    schedule 30.03.2012


Ответы (2)


Что вы можете сделать, так это перегрузить оператор доступа и делегировать его вектору:

class example
{
    public:
        std::vector<std::vector<int>> a;
        int b;

        const std::vector<int>& operator[](std::size_t i) const
        {
            return a[i];
        }
        std::vector<int>& operator[](std::size_t i)
        {
            return a[i];
        }
};

Затем первый [] вернет ссылку на соответствующий элемент a, для которого будет использоваться второй [].

person Christian Rau    schedule 29.03.2012

Одним из наивных решений было бы определить свой собственный operator[]:

class example
{
    std::vector<std::vector<int>> v;
public:
    std::vector<int> const & operator[](std::size_t i) const { return v[i]; }
    std::vector<int>       & operator[](std::size_t i)       { return v[i]; }

    // ...
};

Теперь, если у вас есть example e;, то e[1] — это вектор целых чисел и т. д.

Однако похоже, что вы хотите написать какой-то матричный класс. Для этого более эффективно иметь только один вектор и постепенно получать к нему доступ:

class Matrix
{
    std::size_t cols;
    std::size_t rows;
    std::vector<int> v;

public:
    explicit Matrix(std::size_t r, std::size_t c) : cols(c), rows(r), v(r*c) { }

    int operator()(std::size_t i, std::size_t j) const { return v[i * cols + j]; }
    int & operator()(std::size_t i, std::size_t j) { return v[i * cols + j]; }
};

Теперь вы можете сказать: Matrix m(4, 7); m(1, 3) = 8;. Для этого вы должны использовать оператор круглой скобки, так как оператор квадратной скобки всегда должен принимать ровно один аргумент и поэтому здесь не подходит.

person Kerrek SB    schedule 29.03.2012