If I have a fixed-size 2D array T array[M][N],
I can access elements via array[i][j], and assert(sizeof(array[i]) == N * sizeof(T)).
How can I do it for array wrapped in a struct?
The following code allows to access elements via array[i][j] but fails the assert.
Is there a way for operator[] to return T[N] instead of T* ?
template<class T, int M, int N>
struct Array
{
T data[M][N];
// constexpr T[N] operator[] (int i) - CANNOT RETURN T[N]!
constexpr T* operator[] (int i)
{
return data[i];
}
}
Returning a reference-to-array gives the sizeof you were looking for:
template<class T, int M, int N>
struct Array
{
T data[M][N];
// constexpr T[N] operator[] (int i) - CANNOT RETURN T[N]!
constexpr T (&operator[](int i))[N]
{
return data[i];
}
};
int main()
{
Array<double, 2, 3> a;
std::cout << sizeof(a) << ", " << sizeof(a[1]);
}
Introducing a type alias makes it easier to read
using row = T[N]; // or typedef T (&row)[N]
constexpr row& operator[](int i)
{
return data[i];
}
The different ways to return reference to array C++98/C++03 compatible ways:
Ugly way:
T (&operator[](int i))[N] { return data[i]; }
With typedef:
typedef T arr[N];
arr& operator[](int i) { return data[i]; }
or:
typedef T (&arr_ref)[N];
arr_ref operator[](int i) { return data[i]; }
Since C++11, in addition we have:
with decltype:
decltype(data[i]) operator[](int i) { return data[i]; }
trailing return type:
auto operator[](int i) -> T(&)[N] { return &f; }
or:
auto operator[](int i) -> decltype(data[i]) { return data[i]; }
typedef with using:
using arr = T[N];
arr& operator[](int i) { return data[i]; }
or:
using arr_ref = T(&)[N];
arr_ref operator[](int i) { return data[i]; }
Possibly with template using:
template <typename T, std::size_t N>
using CArray = T[N];
CArray<T, N>& operator[](int i) { return data[i]; }
C++14 adds:
auto deduction:
auto& operator[](int i) { return data[i]; }
decltype(auto) (but careful with deduced return type):
decltype(auto) operator[](int i) { return (data[i]); }
Alternatively, instead of C-array, using std::array would allow more natural syntax
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With