Я пытаюсь написать общую функцию, которая будет выводить возвращаемый тип во время компиляции в соответствии с указанным им итератором. Обычно это делается через std :: iterator_traits, но я также хотел определить свою собственную версию iterator_traits, называемую чертами my_iterator. Вот мой код:Определение пользовательских свойств итератора для общей функции
#include <cassert>
#include <iterator>
#include <vector>
using namespace std;
template <typename I>
struct my_iterator_traits {
typedef typename I::value_type value_type;
typedef typename I::iterator_category iterator_category;
};
template <typename T>
struct my_iterator_traits<T*> {
typedef T value_type;
typedef std::random_access_iterator_tag iterator_category;
};
template <typename II>
typename my_iterator_traits<II>::value_type f(II b, II e) {
typename my_iterator_traits<II>::value_type val = 0;
return val;
}
int main() {
int a[] = {2, 3, 4};
int i = f(a, a + 3);
assert(i == 0);
// vector<int> v = {2};
// f(v.begin(), v.end());
// assert(j == 0);
return 0;
}
Все до и включая main
функции и функции f()
имеет смысл. В основном, я делаю массив int
, вызываю f()
на нем и подтверждаю, что вывод, который я получаю, представляет собой int, значение которого равно нулю.
Что неясно, так это следующее. У меня есть два шаблона вверх, а затем ключевое слово struct
. Было бы разумно использовать второй (тот, который принимает в качестве аргумента шаблона T*
). В частности, зачем нам нужен первый шаблон структуры (один без параметров шаблона)? Что еще более важно, какова взаимосвязь между двумя шаблонами структуры?