I am experimenting with recursive C ++ patterns and I don't know why my pattern is not working.
Let's say I want to define a recursive function that takes a variable number of arguments (for different types).
I looked through many examples of variational patterns, and everything that I have seen so far uses a separate specialized specialization to indicate the base case.
However, I think it would be better (in some cases, at least) to use a single pattern that defines the base case, as well as recursive cases.
I think this approach is especially good if you have a lot of common logic in the function that you have to duplicate for your base example (exactly the same code in two different places).
The second template in the example below should be my solution. I would have thought that this template should function on its own. However, it is not.
Without the first template, the code does not compile:
error: no matching function for call to
'add_elems'
return head[i] + add_elems(i, second, tail...);
^~~~~~~~~
in instantiation of function
template specialization 'add_elems<double, std::__1::vector<double, std::__1::allocator<double> >>' requested here
...
Apparently, the template slows down when it tailconsists of only one parameter. But it should not add_elems(i, second, tail...), but still be valid for a template
template<typename V, typename S, typename... T>
V add_elems(size_t i, const std::vector<V>& head, const S& second, const T&... tail)with an empty one tail?
I don't know if this depends on the compiler, but I use clang.
#include <iostream>
#include <vector>
template<typename V, typename S>
V add_elems(size_t i, const std::vector<V>& head, const S& second)
{
return head[i] + second[i];
}
template<typename V, typename S, typename... T>
V add_elems(size_t i, const std::vector<V>& head, const S& second, const T&... tail)
{
if (sizeof...(tail) > 0)
return head[i] + add_elems(i, second, tail...);
else
return head[i] + second[i];
}
int main()
{
std::vector<double> a({1, -3, -3});
std::vector<double> b({2, -2, 1});
std::vector<double> c({4, -4, -11});
std::vector<double> d({4, 10, 0});
std::cout << "Result: " << add_elems(0, a, b, c, d);
std::cout << " ," << add_elems(1, a, b, c, d);
std::cout << " ," << add_elems(2, a, b, c, d);
}