Определение пользовательских свойств итератора для универсальной функции
Я пытаюсь написать универсальную функцию, которая будет выводить тип возвращаемого значения во время компиляции в соответствии с итератором, который он дал. Обычно это делается с помощью 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*
в качестве аргумента шаблона). В частности, зачем нам нужен первый шаблон структуры (тот, у которого нет параметров шаблона)? Что еще более важно, какова связь между двумя шаблонами структуры?
2 ответа
Первый - это объявление шаблона, а второй - частичная специализация первого. Частичная специализация, подобная объясненной в ссылке, может иметь настройку параметра шаблона (например, некоторые фиксированные параметры, некоторые ограничения того параметра, на который вы ссылаетесь (указатель, ссылки и т. Д.) И т. Д.).
Первый template<typename>struct
это template
Второе - это специализация первого. template
,
template
специализация - это что-то похожее на переопределение (но не совсем), основанное на сопоставлении с образцом. Если аргументы к template
может соответствовать шаблону специализации, он используется вместо этого.
Это сопоставление с образцом не выполняет преобразование типов так же, как переопределения функций. SFINAE находится в игре, однако, для продвинутой работы.