Определение пользовательских свойств итератора для универсальной функции

Я пытаюсь написать универсальную функцию, которая будет выводить тип возвращаемого значения во время компиляции в соответствии с итератором, который он дал. Обычно это делается с помощью 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 находится в игре, однако, для продвинутой работы.

Другие вопросы по тегам