Recursive template function with multiple types

I am trying to write a function that calculates the scalar product for two vectors. Here is the code and it works.

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; } 

But here is the problem: I want to replace these iterators with the type of the template, so the function signature will look something like

  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; } 

But this will not work - I get compilation error C2768: illegal use of explicit template arguments. This seems silly, but I could not understand what I should change to avoid this error.

+6
source share
2 answers

(AFAIK) there is no support for partial specialization of function templates, to get this functionality, you need to do it a little differently, for example:

 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; } }; 
+4
source

Actually, you do not need to use types - I consider them rather bulky, and their semantics are different. You cannot partially specialize a function, but you can overload them and make them behave like specializations by specifying default parameter values:

 #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 } 
+5
source

All Articles