Search code examples
c++iteratorconst-cast

Is it safe to do a const cast here?


I've written my own generic tree implementation, and when writing iterators for it, I am having trouble with const correctness. The issue I am having currently is as follows:

This is the header file for a DFS iterator I wrote:

template<class Item>
class DFSIterator
{
public:
    DFSIterator(const Item& rRootNode);
    ~DFSIterator();
    DFSIterator* First();
    DFSIterator* operator++(int rhs);
    Item* operator*() const;
    Item* operator->() const;
    bool isDone() const;

    template <class Node> friend class Node;

private:
    void initListIterator(const Item* currentNode);

    bool m_bIsDone;
    const Item* m_pRootNode;
    const Item* m_pCurrentNode;
    ListIterator<Item>* m_pCurrentListIter;
    std::map<const Item*, ListIterator<Item>*>  m_listMap;
};

So the bit I am concerned about is the dereference operator:

template<class Item>
Item* DFSIterator<Item>::operator*() const
{
    if(isDone())
    {
        return NULL;
    }
    else
    {
        return const_cast<Item*>(m_pCurrentNode);
    }
}

Is it appropriate to do a const_cast there? I'm wondering if this would cause problems if a user put const objects into the container?


Solution

  • const_casting in itself is always safe, but any attempt to write to const_casted values who have been declared const is undefined behaviour.

    In this case, if your returned pointer points to a value that is declared const and you attempt to modify it, you'll get undefined behavior.


    Rule of thumb: If you need to use const_cast for anything but interoperation with const-incorrect code, your design is broken.


    The standard says in 7.1.6.1 The cv-qualifiers:

    Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.