Search code examples
c++iteratorconstantsconst-iterator

return a const and non const wrapper object


If I want a custom container class to give access to its data through an iterator-like object (actually acting as a wrapper for some data in the container) and I want to be able to get both a const and a non const iterator-like object, one allowing only reading and one reading and writing, so I have to implement two different iterator-like objects; one which allows only reading and one which allows reading and writing, or can I wrap this functionality in one single object.

The issue is that I have to return this object by value but I cannot return a by-value object which cannot directly be put into a non const variable like

const accessor container::getConstAccessor(){/**/}

being misused like

accessor a=myContainer.getConstAccessor(); //effectively giving me a non const

The only solution I can see is to have two accessor classes/structs. One which acts const and one which acts readWrite, regardless of wether they are in a const or non const variable.

This emulates perhaps a constIterator and iterator, but is this truly needed? Can you not make one accessor and return either a const or non const version from the container?

I tried rephrasing this question a few times, to make it most general, but if it makes sense, I am not entirely certain. I hope it does.


Solution

  • Can you not make one accessor and return either a const or non const version from the container?

    Not really. Firstly, you need two accessors as you have to detect whether or not *this is const-qualified:

    /* ??? */ my_container::getAccessor();
    /* ??? */ my_container::getAccessor() const;
    

    Then, if you're returning by value, you have no way of forcing the caller of getAccessor to store the return value in a const variable. That's why you need two different types if you want to enforce immutability in the const-qualified accessor:

    accessor my_container::getAccessor();
    const_accessor my_container::getAccessor() const;
    

    Code repetition can very likely be avoided by implementing both accessor and const_accessor in terms of some template accessor_impl<T> class that can be instantiated with T/const T.