2015-04-27 3 views
1

Я вижу, что многие люди разрешают подписываться int, но мне кажется, что это из-за невежества, потому что это вызывает несоответствия подписей/без знака для типов контейнеров, которые используют unsigned size_type s.Итератор арифметический тип

Поскольку нет способа получить тип контейнера для предоставленных итераторов, я не вижу способа получить size_type предполагаемого контейнера для выполнения точной арифметики.

Какой тип мы должны использовать при выполнении арифметических операций на итераторах? Или еще лучше, как можно получить базовый size_type контейнера, поскольку итераторы не знают своего родительского контейнера?

Edit2:

Что я имею в виду базового типа размера будет, например:

std::vector<some_type>::size_type 

для некоторого итератора, чей контейнер тип std::vector<some_type>

Edit1:

Я думаю, что C++ 17 предоставляет решение этой проблемы через некоторые функции доступа к контейнеру:

Эти функции, не являющиеся членами, предоставляют общий интерфейс для контейнеров, простых массивов и std :: initializer_list.

  • (функция) размер (C++ 17) возвращает размер контейнера или массива
  • (функция) пустые (C++ 17) проверяет, является ли пустой контейнер
  • (функция) данные (C++ 17) получает указатель на базовый массив

Более конкретно размер дает объявленный тип поля размера для родительского контейнера.

+1

В качестве примера «RandomAccessIterator» определяет оператор '+ =' и '+', который принимает целое число со знаком и возвращает итератор. Почему это приводит к предупреждениям о несоответствии подписанных/неподписанных символов или необходимости знать 'size_type'? –

+0

Вы в основном спрашиваете, можете ли вы получить 'size_type' исключительно из итератора? Ответ большой НЕТ, подумайте о реализации, которая реализует итераторы как указатели, у них нет информации о контейнере вообще. Итераторы «знают», как продвигаться, поэтому зачем вам нужен «размер_тип»? – vsoftco

+0

Можете ли вы показать пример, в котором вам дали итераторы, и вам нужен размер 'size_type 'контейнера? Что делать, если итераторы являются указателями на простой массив? – Praetorian

ответ

4

Моя рекомендация заключается в использовании std::iterator_traits<It>::difference_type (It - тип итератора), который обычно (но не обязательно) std::ptrdiff_t. std::ptrdiff_t является псевдонимом подписанного типа.

Я рекомендую это из-за следующие факты:

  1. std::distance возвращается std::iterator_traits<It>::difference_type.
  2. std::next и std::prev принимает std::iterator_traits<It>::difference_type как параметр.
  3. Арифметика на двунаправленном итераторе может идти назад.
+1

полностью забыл о чертах, отличный ответ! – vsoftco

Смежные вопросы