тип итератора
От: Hard_Club  
Дата: 10.03.15 23:06
Оценка: -1
В STL есть несколько типов итераторов http://www.cplusplus.com/reference/iterator/

Только не могу найти соответствующих под-типов. Или разница только в iterator tag

terator tag Category of iterators
input_iterator_tag Input Iterator
output_iterator_tag Output Iterator
forward_iterator_tag Forward Iterator
bidirectional_iterator_tag Bidirectional Iterator
Re: тип итератора
От: night beast СССР  
Дата: 11.03.15 05:21
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>В STL есть несколько типов итераторов http://www.cplusplus.com/reference/iterator/


H_C>Только не могу найти соответствующих под-типов. Или разница только в iterator tag


да.
в бусте есть хелперы для создания своих, но суть от этого не меняется.
Re[2]: тип итератора
От: Hard_Club  
Дата: 11.03.15 10:13
Оценка:
NB>да.
NB>в бусте есть хелперы для создания своих, но суть от этого не меняется.

Тогда как трекается разница в поведении? Т.е. я могу сделать decrement и для forward.

И чего так станно сделано не в ООП-стиле?
Re[3]: тип итератора
От: night beast СССР  
Дата: 11.03.15 10:21
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Тогда как трекается разница в поведении? Т.е. я могу сделать decrement и для forward.


по тагам и трекается. у форворда декремента нет.

H_C>И чего так станно сделано не в ООП-стиле?


ну как бы весь стл сделан не совсем в ООП стиле. никто пока не умер.
да и как ты, например, указатель будешь наследовать?
Re: тип итератора
От: Кодт Россия  
Дата: 11.03.15 12:55
Оценка: +1
Здравствуйте, Hard_Club, Вы писали:

H_C>В STL есть несколько типов итераторов http://www.cplusplus.com/reference/iterator/

H_C>Только не могу найти соответствующих под-типов. Или разница только в iterator tag

В STL используется утиная типизация — не наследование, а контракты.
Если некий итератор является bidirectional, то он является также forward. То есть, принцип подстановки Лисков действует, но на уровне метапрограмм (шаблонов и, не дай боже, макросов).
Чтобы протащить его на уровень указателей/ссылок, придётся использовать, например, boost::any_iterator.

Да, а чтобы можно было различать разновидности (категории) итераторов, выбирая наиболее подходящую специализацию алгоритма (или просто чтоб сделать проверку) — используются тэги и трейтсы.
std::iterator_traits<IteratorType> извлекает из типа информацию
— категория
— тип значения
— тип указателя
и т.п.

Для примитивных типов — т.е. для указателей — эта информация полностью внешняя
template<class Value> struct iterator_traits< Value* > {
  typedef random_iterator_tag iterator_category;
  typedef Value value_type;
  ....
};

А для стандартных и пользовательских классов — обычно выковыривается из самого класса
template<class Iterator> struct iterator_traits {
  typedef typename Iterator::iterator_category iterator_category;
  typedef typename Iterator::value_type value_type;
  ....
};

Чтобы не колбасить ни специализации iterator_traits, ни руками вбивать все определения зависимых имён, используется миксин std::iterator
template<class Category, class Value, class Distance = ptrdiff_t, class Pointer = Value*, class Reference = Value& > struct iterator {
  typedef Category iterator_category;
  typedef Distance difference_type;
  .....
};

У буста иерархия категорий более подробная, чем у STL, но суть такая же.


Проверять категорию нужно через typename iterator_traits<Iterator>::iterator_category, а не непосредственно Iterator::iterator_category, потому что Iterator может быть голым указателем.
Кстати, для простоты проверок и для автоматизации выбора наилучшей специализации алгоритма иерархия категорий сделана на наследовании классов.
Перекуём баги на фичи!
Re[2]: тип итератора
От: Hard_Club  
Дата: 11.03.15 14:10
Оценка:
К>В STL используется утиная типизация — не наследование, а контракты.
К>Если некий итератор является bidirectional, то он является также forward. То есть, принцип подстановки Лисков действует, но на уровне метапрограмм (шаблонов и, не дай боже, макросов).
К>Чтобы протащить его на уровень указателей/ссылок, придётся использовать, например, boost::any_iterator.

Что-то не понял этого утверждения. Он делает стирание типов
Re[3]: тип итератора
От: Кодт Россия  
Дата: 11.03.15 15:19
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Что-то не понял этого утверждения. Он делает стирание типов


Короче, мысль такая. Если тебе нужен вот такой код
void fun( ForwardIteratorInterface<int> i ); // нешаблонная

.....

MyIterator x;
fun(x);

то MyIterator должен приводиться к ForwardIteratorInterface<int>.

И в обычных ООП-языках именно так и делается.
Либо напрямую, чтоб MyIterator наследовался от ForwardIteratorInterface<int>, либо через прокси-объект, реализующий интерфейс и знающий про MyIterator.
Да, происходит стирание типа, поскольку fun() ничего не знает про MyIterator и оперирует интерфейсом.

Для шаблонов этих сложностей не нужно.
Главное, чтобы MyIterator реализовывал контракт, необходимый для fun: например, был CopyConstructible, имел оператор ++ и при разыменовании отдавал int.
Этот контракт можно проверять с помощью SFINAE и static assert'ов. Причём — или каждую фичу контракта, или клятву. Наличие тэга той или иной категории — это клятва.
То, что тэги категорий образуют ООП-иерархию, это просто для удобства.
Перекуём баги на фичи!
Re[4]: тип итератора
От: Hard_Club  
Дата: 11.03.15 16:27
Оценка:
К>Для шаблонов этих сложностей не нужно.
К>Главное, чтобы MyIterator реализовывал контракт, необходимый для fun: например, был CopyConstructible, имел оператор ++ и при разыменовании отдавал int.
К>Этот контракт можно проверять с помощью SFINAE и static assert'ов. Причём — или каждую фичу контракта, или клятву. Наличие тэга той или иной категории — это клятва.
К>То, что тэги категорий образуют ООП-иерархию, это просто для удобства.

Т.е. шаблонный тег разве не может определять имплементацию?
Re[5]: тип итератора
От: jazzer Россия Skype: enerjazzer
Дата: 11.03.15 16:34
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Т.е. шаблонный тег разве не может определять имплементацию?


может, и определяет. Можешь посмотреть на реализацию std::advance.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.