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
.