c++constantsoperator-overloadingconst-correctness

How can the object parameter received by an input overloading function be const


In class we're implementing vector, but I don't understand why the code for the input operator overloading is working:

istream& operator>> (istream& in, const Vector& A)
{
    for (int i = 0; i < A.size; i++)
        in >> A.data[i];
    return in;
}

I tried the code and it worked pretty well, but how can the vector reference be const even though we're inputting values for A?!


Solution

  • Assuming that Vector contains some T* data pointer as a member, a const Vector's member would be a T* const pointer. T* const is a const pointer to T, though T is mutable.

    Therefore, in >> A.data[i]; works, since it simply writes mutable data.

    If you want constness to propagate deeply to the next pointer, you have to ensure this yourself:

    class Vector {
    private:
        T* m_data;
    
    public:
        T* data() {
            return m_data;
        }
        const T* data() const {
            return m_data;
        }
    };
    

    Now, in >> A.data()[i] would fail because A.data() would yield a pointer to const T.

    This technique is used by containers like std::vector, see std::vector::data.

    Note on language evolution

    There is std::experimental::propagate_const which solves this without extra manual effort.

    P2670: Non-transient constexpr allocation proposes a propconst specifier which would could be used as follows:

    struct Vector {
        // propagate const one level deep
        propconst(1) T* data;
    };