This works perfectly :
list<int> l;
list<int>::const_iterator it;
it = l.begin();
list<int>::iterator it2;
it2 = l.begin();
What I don’t get is how the list "knows" that it must return the iterator begin() version or the const_iterator begin() const one.
I’m trying to implement iterators for my container (a trie) and I’m running into this problem. Isn’t C++ supposed not to handle differentiation by return type (except when using weird tricks)?
Here is some code and the compiler error I get :
My Trie<T> is a templated trie that can contain any type. I have a Trie<int>::iter non-const iterator and a Trie<int>::const_iter const iterator. iter begin() and const_iter begin() const are declared (and defined) in the Trie class.
Trie<int> t;
Trie<int>::const_iter it;
it = t.begin();
Error :
../test/trie.cpp:181: error: no match for 'operator=' in 'it = Trie<T>::begin() [with T = int]()'
[..path..]/Trie.h:230: note: candidates are: Trie<int>::const_trie_iterator& Trie<int>::const_trie_iterator::operator=(const Trie<int>::const_trie_iterator&)
So, I believe the non-const version of begin is not used.
I contemplated creating an operator=(const Trie<T>::const_trie_iterator&) method for the non-const iterator but I don’t see that in the STD lib and I would have to const_cast the iterator. What should I do?
In standard containers, a non-const iterator is implicitly convertible to a const_iterator. The type returned is based solely on the const-ness of the object/reference on which
begin()was called, which in your case would beiterator, there is a conversion that allows the later assignment.In particular in the 23.2.1 General Container Requirements, table 96, it says that
X::iteratormust be convertible toX::const_iterator.