Search code examples
c++c++14c++17variadic-templatesgeneric-programming

variadic templates vs using tuples for adding different data pairs in an argument


following main code works fine

    string hello = "Hello ";
    string world = "templates!";

    cout << "var template add: ";


    cout << setprecision(2) <<
        var_template_add(5, 4, 5.5, 4.0);

for following template generator code and variadic func

template <typename T> 
auto add(T a, T b) {
    return a + b;
}


template <typename T, typename... Rest> 
auto var_template_add(T first, T second, Rest... others) {
    return first + second + add (others...);
}

But if added two more string args, like this

var_template_add(5, 4, 5.5, 4.0, hello, world);

is caught by compiler error saying "no matching overloaded function found".

Again,

string hello = "Hello ";
string world = "templates!";
cout << "strings add result: " << setprecision(2) << add(hello, world) << endl;

could work if i write template function "add" like below:

template <typename T1, typename T2>
auto add(T1 a, T2 b) {
    return a + b;
}

My question is, how could i make the line

var_template_add(5, 4, 5.5, 4.0, hello, world);

work without writing another add function like just above?!

please note i could use tuple to pass this values but for now, i just want to keep away. any thoughts/improvements?


Solution

  • The only way for the current call to work is for var_template_add to return a single type, so it would need to be a string.

    Instead, you could write the cout inside the function, so then you only need:

    template <typename T, typename... Rest> 
    auto var_template_add(T first, T second, Rest... others) {
        cout << setprecision(2) << (first + second) << " ";
        if constexpr (sizeof...(others)) var_template_add(others...);
    }
    

    Here's a demo.

    Note that there is no if constexpr pre c++17, so in that case, having an extra overload as base case is a good option.