In this code, why is
- the constness of
GetAutoRef
andGetAutoRefJ
's return values different, - the return value of
GetDecltypeAutoJ
not const?
#include <type_traits>
struct A {
int i;
int& j = i;
decltype(auto) GetDecltypeAuto() const { return i; }
auto GetAuto () const { return i; }
auto& GetAutoRef () const { return i; }
decltype(auto) GetDecltypeAutoJ() const { return j; }
auto GetAutoJ () const { return j; }
auto& GetAutoRefJ () const { return j; }
};
int main() {
A a{5};
static_assert(std::is_same_v<decltype(a.GetDecltypeAuto()), int> );
static_assert(std::is_same_v<decltype(a.GetAuto() ), int> );
static_assert(std::is_same_v<decltype(a.GetAutoRef()), const int&>); //as expected
static_assert(std::is_same_v<decltype(a.GetDecltypeAutoJ()), int&>); // no const?
static_assert(std::is_same_v<decltype(a.GetAutoJ() ), int> );
static_assert(std::is_same_v<decltype(a.GetAutoRefJ() ), int&>); // no const?
}
Shouldn't j
be const if accessed through the const
this
pointer in the J
functions?
As NathanOliver explained, the
const
is applied to the reference itself, not the referenced type.This might seem confusing, and it might help to remember that reference are mostly just "convenient pointers". If you use a pointer instead, things become more obvious:
In
GetDecltypeAutoK
, the type ofthis->k
isint* const
, i.e. notint const*
. Dereferencing anint* const
gives you anint
.It's the same in
GetDecltypeAutoJ
: the type ofthis->j
isint& const
which is identical toint&
since references are always constant.