Consider the following code:
struct A
{
using type = int;
using reference = int&;
};
static_assert(std::is_same_v<A::type&, A::reference>); // <-- Success, as it would be
static_assert(std::is_same_v<const A::type&, const A::reference>); // <-- Fail!!
What is going on?? Why they are not the same type anymore? I spent lot of time finding this and it really seems a compiler bug
First,
const int&is, so to speak, a reference to constant int, not a constant reference to int. Thus addingconstkeyword toA::referenceproduces a beast that spelled asint& constinstead ofconst int&(or equally fineint const &).So yes, as a reference cannot be rebound to different object, it is de facto constant without any keywords. Thus that
constafter an ampersand is excessive. Looks like it is silently dropped, I cannot cite standard on required compiler behavior, see comment by @Quentin.Second, the answer may depend on what you really want to achieve. If
Ais a container, it should have aA::const_referencemember type, which you should use. If it is a more generic range rather than a container, itsreferenceandconst_referencemember types might be two completely unrelated proxy object classes. If you controlA, add aconst_referencemember type. Otherwise, @Evg provided a solution that will do. Maybe a more simple solution is justconst std::decay_t<A::reference>&.