Search code examples
c++const-correctness

Const correctness in C++


I have simple data structure called array (similar to std::array). array class have method called all(). Here are method declarations:

const range<const_type_pointer> all() const;
range<type_point> all();

range is class template, which is constructed by two iterators. Here is simplified version of range class declaration:

template <typename Iterator>
class range {

    typedef typename iterator_traits<Iterator>::type_value type_value;
    typedef typename iterator_traits<Iterator>::type_reference type_reference;
    typedef typename iterator_traits<Iterator>::type_pointer;

    range(Iterator begin, Iterator end);
// methods & algorithms

// data members

    mutable Iterator _begin;
    mutable Iterator _end;
};

So basically, if I call method all on const array object, it should call const overload of method and return const range. Now, in my algorithms section, I have simple algorithm with following signature:

    template <typename UnaryFunction>
    range forEach(UnaryFunction function);

Then I tried following test:

void test1(const array<int, 10>& array)
{
    auto r = array.all();
    r.forEach([](int i) { std::cout << i << " "; });
}

And second one:

void test2(const array<int, 10>& array)
{
    auto r = array.all();
    r.forEach([](int& i) { ++i; });
}

In first case, where I was just printing variable i, compiler did not complained, even though I called non-const range method on const range object. In second case, compiler complained. Is this behaviour standard confornant?

As a compiler, I am using MSVS compiler.


Solution

  • First. Sice you are returning by value, it doesn't really make any difference if you are returning const range or range.

    Second. auto r = array.all(); creates a copy of whatever was returned by all. Your r is a non-const object, and non-const forEach is used. But since the iterator is const in the second version, you can't modify the iterable.