Home > Software engineering >  Returning type of operator[] in 2d array template class using std::vector
Returning type of operator[] in 2d array template class using std::vector

Time:10-30

I have my class Table below. Pay attention at the way I have implemented operator[]. The reason i have used decltype(auto) as a return type is because (to my knowledge at least) when you would apply your operator twice in row (eg. my_table[i][j] ), the returned types are different: after first application it would be a vector& after the second consecutive application it would be T. It works fine and well but to my surprise if I just rewrite operator[] as follows it still works fine:

vector<T>& operator[](size_t input) const{
    return data[input];
}

The question is WHY? how does it return the required reference to the requested element in t[i][j]?

Original code:

template <typename T>
class Table{
public:
    Table(size_t r_num, size_t c_num) : data(r_num , vector<T> (c_num, T{})) {}

    decltype(auto) operator[](size_t input) const{
        return data[input];
    }
    decltype(auto) operator[](size_t input){
        return data[input];
    }
    void Resize(size_t r_num, size_t c_num){
        data.resize(r_num);
        for(auto& it : data)
            it.resize(c_num);
    }
    pair<size_t,size_t> Size() const{
        if(data.empty() || data[0].empty())
            return pair{0, 0};
        return pair{data.size(), data[0].size()};
    }
private:
    vector<vector<T>> data;

};

CodePudding user response:

my_table[i][j] = 3 is essentially the same thing as:

auto& tmp = my_table[i];
tmp[j] = 3;

Taking that into consideration, both of these are actually 100% equivalent:

vector<T>& operator[](size_t input) {
    return data[input];
}

// same thing as

decltype(auto) operator[](size_t input) {
    return data[input];
}

They both return a std::vector<int>&, and the second indexing operation applies to that vector.

So why do you need to use decltype(auto) then? It's because auto strips out references:

auto operator[](size_t input) {
    return data[input];
}

// same thing as

vector<T> operator[](size_t input) {
    return data[input];
}

Which returns a copy of the row, and would prevent assignment.

CodePudding user response:

We have:

Table t;
t[i][j] = 7; 

While the first operator[] applied is overloaded in class Table(returns: vector<T>&), the second operator[] would apply to the vector<T>& and thus its already an operator that is overloaded for class vector not class table.

  • Related