Зачем использовать iterator_traits в функции шаблона вместо того, чтобы просто использовать другой аргумент типа шаблона?

Ссылаясь, например, на этот фрагмент из cplusplus.com:

template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count(InputIterator first, InputIterator last, const T& val)
{
typename iterator_traits<InputIterator>::difference_type ret = 0;
while (first!=last) {
if (*first == val)
++ret;
++first;
}
return ret;
}

Вопрос в том, зачем использовать iterator_traits в этом контексте, вместо того, чтобы принимать другой аргумент шаблона, как показано здесь:

template <class InputIterator, class T, class DiffType>
DiffType count(InputIterator first, InputIterator last, const T& val)
{
DiffType ret = 0;
while (first!=last) {
if (*first == val)
++ret;
++first;
}
return ret;
}

3

Решение

Предложение, которое вы предложили в комментариях — функция должна принимать другой аргумент шаблона — не будет работать так, как вы предполагали. Вот код, который вы предложили:

template <class InputIterator, class T, typename DiffType>
DiffType count(InputIterator first, InputIterator last, const T& val)
{
DiffType ret = 0;
while (first!=last) {
if (*first == val)
++ret;
++first;
}
return ret;
}

Проблема с этим кодом в том, что он больше не компилируется:

std::vector<int> v = /* ... */;
auto numElems = count(v.begin(), v.end(), 137); // <--- Error!

Проблема здесь заключается в том, что для вызова шаблона функции каждый аргумент шаблона должен быть либо выводимым из типов аргументов, либо явно указанным вызывающей стороной. Здесь тип DiffType не может быть выведено из типов аргументов ( InputIterator а также T типы могут быть выведены из двух аргументов, но только из сигнатуры нет контекста), поэтому этот вызов завершится с ошибкой компилятора. Использование std::iterator_traits Вот шаблон общего шаблона для извлечения информации об итераторе из самого типа итератора.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]