Ссылаясь, например, на этот фрагмент из 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;
}
Предложение, которое вы предложили в комментариях — функция должна принимать другой аргумент шаблона — не будет работать так, как вы предполагали. Вот код, который вы предложили:
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
Вот шаблон общего шаблона для извлечения информации об итераторе из самого типа итератора.
Других решений пока нет …