Search code examples
c++c++17qualifiers

Why is the const qualifier in this type alias dropped?


TL;DR

Given the following type:

struct A
{
    std::vector<std::string> vec;

    using reference = std::iterator_traits<decltype(vec)::iterator>::reference;
    using const_reference = const reference;
};

Why is reference == const_reference? Why is the const qualifier dropped in the second type alias?

See the example on godbold which shouldn't compile.

Details

I have a templated class that takes a bunch of iterators (-types) as template arguments. From these iterators I need to deduce the reference and const reference type because I have some member functions like:

struct A
{
    std::vector<std::string> vec;

    using reference = std::iterator_traits<decltype(vec)::iterator>::reference;
    using const_reference = const reference;

    const_reference foo() const
    {
        return vec[0];
    }
};

By dropping the const qualifier, I'm effectively returning a reference in foo which is illegal because it's a const member function and so the compiler throws.


Solution

  • It is dropped. What we call a "const reference" is really a reference to const - const int&.

    Having an int& and adding const would make that int& const. But such a const is dropped.

    Your problem is similar to the difference between const int* and int* const. Except that for references, int& and int& const is the same type - the const is ignored.