виртуальный прямой итератор? - PullRequest
4 голосов
/ 30 мая 2011

Я посмотрел на прямой итератор STL.Я нигде не вижу виртуальных функций.Если у меня есть библиотека, которая хочет прямой итератор строк, как я могу позволить функции принимать любой прямой итератор, который возвращает строки?Есть ли в стандартной библиотеке что-нибудь, что я могу использовать?

Ответы [ 4 ]

6 голосов
/ 30 мая 2011

Виртуальных методов не существует, так как они предназначены не для полиморфного (в обычном смысле полиморфизма во время выполнения), а для шаблонов (статический полиморфизм).Обычный подход заключается в том, чтобы иметь функцию, которая принимает итераторы на основе типа итератора.Вы можете найти много примеров в заголовке алгоритма STL:

template <class InputIterator, class Distance>
inline void distance(InputIterator first, InputIterator last, Distance& n);

В вашем конкретном случае:

template <class ForwardIterator> // or InputIterator or whatever your needs are
void acceptIterators( ForwardIterator start, ForwardIterator end );

Дополнительное ограничение на ссылки на строки может быть реализовано в терминахнаберите traits и enable_if:

template <class ForwardIterator>
std::enable_if< std::is_same< std::string,
                              typename iterator_traits<ForwardIterator>::value_type > >
void acceptIterators( ForwardIterator start, ForwardIterator end );

Использование typetraits из c ++ 0x, но enable_if и is_same доступны в boost, если они вам нужны в компиляторе, который их не поддерживает.

Если вам нужно иметь возможность переключать типы итераторов во время выполнения, вы можете посмотреть any_iterator, который выполняет стирание типов на конкретных итераторах, обеспечивая полиморфный интерфейс во время выполнения.Это описано в статье О противоречии между объектно-ориентированным и общим программированием в C ++ , реализацию можно найти в Adobe STLab .

1 голос
/ 30 мая 2011

Вы можете написать свой собственный итератор и использовать его как:

std::for_each( make_myiterator(c.begin), make_myiterator(c.end), do_some() );

Вы можете наследовать от std::iterator или установить Boost Iterator Facade - это поможет вам написать собственный итератор.

0 голосов
/ 30 мая 2011

Если вы хотите принять любой итератор, например, строки, вам нужно использовать шаблоны.Не существует класса итераторов верхнего уровня, который наследуют все другие итераторы.

Написание совместимых итераторов C ++ может быть затруднительно, но Boost.Iterators очень поможет вам, если вы не боитесь шаблонов.Есть пример того, как использовать iterator_facade для создания простого итератора, на который вы должны взглянуть.Boost.Iterators - это библиотека только для заголовков, поэтому нет необходимости связывать что-либо с вашим приложением / библиотекой.

0 голосов
/ 30 мая 2011

Обычный способ - создавать функции, использующие шаблоны-функции итератора.Это то, что делает стандартная библиотека.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...