2013-12-09 13 views
6

Próbuję napisać funkcję, która zlicza produkt skalarny dla dwóch wektorów. Oto kod i to działa.Funkcja szablonu rekursywnego z wieloma typami

template <int N> 
    int scalar_product (std::vector<int>::iterator a, 
         std::vector<int>::iterator b) { 
     return (*a) * (*b) + scalar_product<N - 1>(a + 1, b + 1); 
    } 

    template <> 
    int scalar_product<0>(std::vector<int>::iterator a, 
          std::vector<int>::iterator b) { 
     return 0; 
    } 

Ale tutaj jest problem - chcę zastąpić ten iteratory z typu szablonu tak, że podpis funkcji będzie wyglądać smth jak ten

template <typename Iterator ,int N> 
    int scalar_product (Iterator a, Iterator b) { 
     return (*a) * (*b) + scalar_product<N - 1>(a + 1, b + 1); 
    } 

    template <typename Iterator> 
    int scalar_product<0>(Iterator a, 
          Iterator b) { 
     return 0; 
    } 

Ale to nie działa - mogę skompilować błąd C2768: nielegalne użycie jawnych argumentów szablonu. Wydaje się to głupie, ale nie mogłem się dowiedzieć, co powinienem zmienić, aby uniknąć tego błędu.

+0

zobaczyć to: http://stackoverflow.com/questions/3716799/partial-specialization- of-function-templates – Nim

+0

Dlaczego nie używać ['std :: inner_product'] (http://en.cppreference.com/w/cpp/algorithm/inner_product)? Czy twoja pętla jest dla ciebie tak ważna? – gwiazdorrr

+0

@Nim Dzięki za link - pomógł. – htzfun

Odpowiedz

4

(AFAIK) nie ma wsparcia dla częściowej specjalizacji szablonów funkcyjnych, aby uzyskać tę funkcję, trzeba zrobić to nieco inaczej, coś takiego:

template <int N> 
struct scalar 
{ 
    template <typename Iterator> 
    static int product(Iterator a, Iterator b) 
    { (*a) * (*b) + scalar<N - 1>::product(a + 1, b + 1); } 
}; 

template <> 
struct scalar<0> 
{ 
    template <typename Iterator> 
    static int product(Iterator a, Iterator b) 
    { return 0; } 
}; 
5

Właściwie nie trzeba używać typy - uważam je za dość kłopotliwe, a ich semantyka jest inna. Nie można częściowo specjalizują się funkcji, ale można je przeciążenie i uczynić je zachowywać się jak specjalizacji, zapewniając parametry domyślne wartości:

#include <type_traits> 

template <typename Iterator> 
int scalar_product(Iterator a, Iterator b, std::integral_constant<int, 0> = std::integral_constant<int, 0>() ) 
{ 
    return 0; 
} 

template <int N, typename Iterator> 
int scalar_product (Iterator a, Iterator b, std::integral_constant<int, N> = std::integral_constant<int, N>()) 
{ 
    return (*a) * (*b) + scalar_product(a + 1, b + 1, std::integral_constant<int, N-1>()); 
} 

int foo() 
{ 
    int a[] = { 1, 2, 3, 4 }; 
    int b[] = { 1, 1, 1, 1 }; 
    return scalar_product<4>(a, b); // returns 10 
} 
Powiązane problemy