Yet another question on overloading an []
operator in C++, in particular, its const
version.
According to cppreference page on operator overloading, when overloading an array subscript operator
struct T { value_t& operator[](std::size_t idx) { return mVector[idx]; } const value_t& operator[](std::size_t idx) const { return mVector[idx]; } };
If the value type is known to be a built-in type, the const variant should return by value.
So, if value_t
happens to be a built-in type, the const
variant should look
const value_t operator[](std::size_t idx) const { return mVector[idx]; }
or probably even
value_t operator[](std::size_t idx) const { return mVector[idx]; }
since the const
qualifier is not very useful on such a return value.
Now, I have a templated class T
(to keep the same naming as with the reference), which is used both with built-in data types and user-defined ones, some of which might be heavy.
template<class VT>
struct T
{
VT& operator[](std::size_t idx) { return mVector[idx]; }
const VT& operator[](std::size_t idx) const { return mVector[idx]; }
};
According to the given advice above, I should use enable_if
with some type_traits
to distinguish between templated class instantiations with built-in/not built-in types.
Do I have to do it? Is this recommendation only to avoid potential unnecessary dereferencing for built-in types or something else is hiding behind it that one should be aware of?
Notes:
- this class actively participates in a hot part of the code instantiated both with built-in and custom types.
- code is used cross-platform with multiple compilers with varying degrees of optimization options.
- thus, I am interested in making it both correct & portable, as well as avoid any potential detriment to performance.
- I was not able to find any additional reasoning in C++ standard, but reading standardeze is not my strongest suit.
Existing questions on StackOverflow:
- C++ FAQ entry on basic rules and idioms for operator overloading recommends returning a copy using a "should better" construct without explicit justification. This "should better" is slightly different than "should" in the cppreference page and adds up to my confusion.
- this and this talk about const overloading in principle; however, not about the detail that interests me. Also, the first uses
const value_t&
and the secondconst value_t
.