2014-07-16 2 views
0

Я пытаюсь написать общую функцию, которая будет выводить возвращаемый тип во время компиляции в соответствии с указанным им итератором. Обычно это делается через 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*). В частности, зачем нам нужен первый шаблон структуры (один без параметров шаблона)? Что еще более важно, какова взаимосвязь между двумя шаблонами структуры?

ответ

0

The первого это объявление шаблона и второго является partial specialization из первых. Частичная специализация, как описано в ссылке, может иметь настройку параметра шаблона (например: некоторые фиксированные параметры, некоторое ограничение того, к какому параметру вы обращаетесь (указатель, ссылки и т. Д.) И т. Д.).

0

Первый template<typename>struct - template, второй - специализация первых template.

template специализация - это нечто похожее на переопределение (но не на самом деле), основанное на совпадении шаблонов. Если аргументы template могут быть сопоставлены шаблоном специализации, он используется вместо этого.

Этот шаблон не выполняет преобразование типа таким же образом, что и функции переопределения. Однако SFINAE находится в игре, для продвинутой работы.

Смежные вопросы