Stack Exchange
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?

And what is 5 + "hello"?

If your + operation is associative, no additional template function is required, it is pretty easy to have another overload. And in C++17 there are always fold expressions, no template function is needed at all.

@Evg thats not intention. since + operator will expect 2 argument at one time, above exp is supposed to be evalulated like (5+4) + (5.5, 4.0) + (hello + world) but i think i got what you meant.

OK, what is 9 + 9.5 + "helloworld"? What is the expected output of var_template_add(...)?

@Evg i think i got the point. i am gonna try overloading + op for adding an int and string. :D so it could print 18.5helloworld and return as string as pointed by cigien

This question is tagged c++11, but the snippets use C++14 auto return types without a trailing return type definition. Is the tag incorrect?

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.

Thank @cigien what if i dont wish to use cout inside the template function?!

Depends on what you want var_template_add to return. Do you want to return a string?

This solution is C++17 due to "if constexpr", but the question is tagged C++11

@Human-Compiler True, didn't even notice that :p Added the caveat.

it skips the last addition though. its funny. e.g. var_template_add (5, 4, 5.5, 4.0, hello, world) donst print "hello template"

It does print it. Did you see the demo link?

This code fails to compile with odd numbers of arguments.

@ildjarn True, but looks like OP always wants to use this function with an even number of arguments.

Adding std::string to integral values will not work unless you choose to make your function explicitly convert to string, such as using a std::stringstream or std::to_string.
If you want this to behave correctly with stringizing behavior, you will need to change it to do some form of explicitly string building.
However, you can at least make your current var_template_add work with any number of arguments, since the current definition requires 4 arguments or it will not work. This will allow the var_template_add(hello, world) example to work.

In C++11 this can be done by using some template recursion. This doesn't require adding any new functions per-se -- just renaming an existing one and altering one.
The idea is to recursively call the var_template_add until you end up with 2 arguments, and then just add the two together:
// rename'add' to 'var_template_add'. Use this as recursive base-case.
template <typename T, typename U> 
auto var_template_add(T first, U second) 
  -> decltype(first + second)
{
    return first + second;
}

// adds first argument and delegates 'second' and 'others...' to the next 'var_template_add'
template <typename T, typename U, typename... Rest> 
auto var_template_add(T first, U second, Rest... others) 
  -> decltype(first + var_template_add(second, others...))
{
    return first + var_template_add(second, others...);
}

For 2 arguments, it will call the first overload. For 3 or more arguments, it will call the second, which will recursively call into the next var_template_add, until eventually calling into the first.
Note: This answer is because the question is tagged C++11 -- but please be aware that your use of auto return types without a trailing return type is actually C++14 and not C++11.

If you have C++17, you can do this even easier using variadic fold expressions:
template <typename T, typename U, typename...Rest>
auto var_template_add(T first, U second, Rest...others)
{
    return first + second + (... + others);
}


Edit:
Since OP updated the tags to include c++14 and c++17, you can achieve the stringizing add behavior quite easily using either to_string or stringstream and a fold expression. For this, I do recommend a different function though -- since appending string sequences is semantically quite a different operation from "adding" values.
The best approach would probably be to use std::stringstream, something like:
template <typename...Args>
std::string variadic_add_str(Args&&...args)
{
    auto stream = std::string_stream{};
    stream << (... << std::forward<Args>(args));
    return stream.str(); 
}


still the same issue used this code. "no overload func found". have not tried the C++17 code. nope either of this code doesnt work for the problem described. have to tested your code ?

Didn't test with the string + int/float input because it operator+ wouldn't work for that. The issue there would be that T is used for both first and second. If those two types were different template arguments, it should work fine. The C++17 version doesn't have this issue because I wrote it differently.

@Amaresh I've updated to add a different template type for second, which will fix the overload problem. But this still will not address that string is not able to be added with int or float because there is no operator+ between them
