void printconst list lstostream out cout typename container::iterator itr lst begin)whileitr !lst endout <*itr <endl*itr /this is fishy!!++itrif this code were legalthen the const-ness of the list would be completely meaninglessbecause it would be so easily bypassed the code is not legal and will not compile the solution provided by the stl is that every collection contains not only an iterator nested type but also const_iterator nested type the main difference between an iterator and const_iterator is that operatorfor const_iterator returns constant referenceand thus *itr for const_iterator cannot appear on the left-hand side of an assignment statement furtherthe compiler will force you to use const_iterator to traverse constant collection it does so by providing two versions of begin and two versions of endas followsr iterator beginr const_iterator beginconst iterator endr const_iterator endconst the two versions of begin can be in the same class only because the const-ness of method ( whether it is an accessor or mutatoris considered to be part of the signature we saw this trick in section and we will see it again in section both in the context of overloading operator[if begin is invoked on nonconstant containerthe "mutatorversion that returns an iterator is invoked howeverif begin is invoked on constant containerwhat is returned is const_iteratorand the return value may not be assigned to an iterator if you try to do soa compiler error is generated once itr is const_iterator*itr= is easily detected as being illegal if you use auto to declare your iteratorsthe compiler will deduce for you whether an iterator or const_iterator is substitutedto large extentthis relieves the programmer from having to keep track of the correct iterator type and is precisely one of the intended uses of auto additionallylibrary classes such as vector and list that provide iterators as described above are compatible with the range-based for loopas are user-defined classes an additional feature in ++ allows one to write code that works even if the container type does not have begin and end member functions non-member free functions begin and end are defined that allow one to use begin(cin any place where begin(is allowed writing generic code using begin(cinstead of begin(has the advantage that it allows the generic code to work on containers that have begin/end as membersas well as those that do not have begin/end but which can later be augmented with appropriate