Search code examples
c++templatesc++14metaprogrammingvariadic-templates

How to pass other template parameter when template function uses parameter pack?


Is it possible to have other template parameter when function/class uses parameter pack?

I try simple sum function. I want to print something using template Printer class. How to do that? How to tell compiler to specially "mark" first parameter... or there is some workaround.

Below code generates errors.

#include <iostream>

template <typename T>
double sum(T t)
{
    return t;
}

template <typename Printer, typename T, typename... Rest>
double sum(Printer printer, T t, Rest... rest)
{
    printer.print();

    return t + sum(rest...);
}

struct P
{
    void print() { std::cout << "= " << std::endl; }
};

int main()
{
    P printer;
    std::cout << sum(printer, 2, 3, 4.1) << std::endl;
    return 0;
}

Solution

  • You get an error because the only sum overload that accepts more than a single argument expects the first argument to be a printer object. Since you want to print only once, the cleanest approach would be to separate the summation into its own function entirely:

    template <typename T>
    double sum_impl(T t)
    {
        return t;
    }
    
    template <typename T, typename... Rest>
    double sum_impl(T t, Rest... rest)
    {
        return t + sum(rest...);
    }
    

    and then use that in sum

    template <typename Printer, typename T, typename... Rest>
    double sum(Printer printer, T t, Rest... rest)
    {
        printer.print();
    
        return sum_impl(t, rest...);
    }