Итераторы и шаблоны - PullRequest
       11

Итераторы и шаблоны

6 голосов
/ 22 февраля 2011

Я пытаюсь реализовать функцию, которая позволяет пользователю вводить некоторый тип начального и конечного итератора, а затем все выполняют некоторую операцию с данными.Однако эта функция должна быть достаточно общей и работать для многих типов итераторов (например, std::vector::iterator, std::string::iterator, std::iterator и т. Д.).Единственным ограничением является то, что итераторы должны иметь как минимум forward_iterator_tag возможностей.

Мой прототип функции выглядит следующим образом:

template <class key_type, class data_type> std::shared_ptr<data_type> 
    remove(std::iterator<std::forward_iterator_tag, key_type> key_start, 
    std::iterator<std::forward_iterator_tag, key_type> key_end);

Однако это ограничивает меня использованием конкретно forward_iterator_tag итератор, поэтому попытка вызвать функцию следующим образом:

remove<char, char>(std::iterator<std::random_access_iterator_tag, char>(), std::iterator<std::random_access_iterator_tag, char());

не удастся, потому что компилятор не может преобразовать std::iterator<std::random_access_iterator_tag,...> в std::iterator<std::forward_access_iterator_tag,...>.Кроме того, этот метод не работает для строковых итераторов, векторных итераторов или других итераторов stl.

Кто-нибудь знает, как stl реализует контейнеры / строки для приема итераторов друг от друга?Например, это правильно компилируется:

std::string a = "hello";
std::vector<char> v(a.begin(), a.end());

1 Ответ

13 голосов
/ 22 февраля 2011
template < typename Iter >
void fun_impl(Iter begin, Iter end, std::forward_iterator_tag)
{
  // do your stuff here...
}

template < typename Iter >
void fun(Iter begin, Iter end)
{
  fun_impl(begin,end, std::iterator_traits<Iter>::iterator_category());
}

Типы, возвращаемые begin() и end() для различных контейнеров, относятся не к типу iterator<category...>, а к подклассам таких (иногда).При написании универсального кода вы никогда не нацеливаетесь на определенный тип итератора.Вместо этого вы используете «диспетчеризацию тегов» для классификации итератора и вызова правильной реализации.Так как random_iterator_tag is-a forward_iterator_tag, он будет автоматически преобразован в такой, чтобы вышеуказанное значение fun_impl было правильно разрешено для любого forward_iterator или расширения.

...