есть код:
#include <list>
template< typename T >
class Foo
{
public:
class iterator
{
public:
iterator& operator++() { return *this; }
bool operator!=( const iterator& ) { return false; }
};
class const_iterator
{
public:
const_iterator& operator++() { return *this; }
bool operator!=( const const_iterator& ) { return false; }
};
iterator begin() { return iterator(); }
iterator end() { return iterator(); }
const_iterator begin() const { return const_iterator(); }
const_iterator end() const { return const_iterator(); }
};
int main( int, char** )
{
// typedef std::list<int> test_t;
typedef Foo<int> test_t;
test_t t;
for ( test_t::const_iterator i = t.begin(), e = t.end(); i !=e; ++i )
;
return 0;
}
при компиляции и GCC и MSVC8 выдают ошибку:
$ g++ m3.cpp
m3.cpp: In function `int main(int, char**)':
m3.cpp:37: error: conversion from `Foo<int>::iterator' to non-scalar type `Foo<int>::const_iterator' requested
m3.cpp:37: error: conversion from `Foo<int>::iterator' to non-scalar type `Foo<int>::const_iterator' requested
при замене с Foo<int> на std::list<int> все компилируется на ура.
Внимание, вопрос -- неужели все дело в том, что в стандартных хидерах есть преобразование из
iterator в
const_iterator? У msvc итератор вообще наследуется от константного...
Мой реальный класс гораздо сложнее, и мне очень не хочется в цикле
for ( test_t::const_iterator i = t.begin(), e = t.end(); i !=e; ++i )
допускать появление неконстантного итератора, указывающего на начало списка.
Или я чего-то не понимаю с const — функциями?
Как компилятор выбирает, какую функцию дернуть -- const или не-const?
Почему в данном случае он игнорирует
const_iterator begin() const { return const_iterator(); }
const_iterator end() const { return const_iterator(); }
?