Передача итератора в качестве аргумента - PullRequest
0 голосов
/ 05 марта 2019

Я пытаюсь написать шаблонную функцию, которая может принимать любой итератор в качестве аргумента.

Например, я должен иметь возможность передавать массивы, списки, векторы всех типов через эту функцию.

Я думал о написании функции следующим образом:

enter template<typename T1, T2>
int proof(T1<T2>::iterator& it, T1<T2>::iterator& itt){

return distance(it, itt);
}

Где T1 должен быть типом контейнера, а T2 должен быть арифметическим типом.

В идеале я бы хотел передать массив и вектор с помощью этой функции.

Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Это хорошая идея, но склонная к сбою - учтите, например, что vector имеет аргумент шаблона Allocator, который по умолчанию установлен, и вы редко указываете себя, но всегда присутствует.Итак, ваш самый простой вариант использования более сложен, чем предполагалось, и кто знает, какие сюрпризы могут преподнести другие контейнеры?

Вместо этого просто используйте тип итератора напрямую.Если код внутри функции работает с итератором, то отлично.Если нет, то он не скомпилируется (или ваши пользователи нарушили задокументированное предварительное условие).Если это работает с чем-то, что вы лично не называете «итератором», то это имеет значение?Это работает!

template <typename Iterator>
auto proof(const Iterator& it1, const Iterator& it2)
{
   return std::distance(it1, it2);
}

Конечно, я не рекомендую писать такую ​​функцию, если только она не делает что-то более существенное, чем делегирование std::distance;например, ваш тип возврата был неправильным.

0 голосов
/ 05 марта 2019

Чтобы написать шаблон, который может принимать любой итератор, просто примите любой тип:

template<class It>
int proof(const It&, const It&)

С другой стороны, ваш шаблон ничего не делает, кроме как передает аргументы вперед std::distance, поэтому он не 'Кажется, это действительно добавляет какую-то ценность.Возможно, лучше просто использовать std::distance напрямую.

...