I would like to understand variadic templates a little bit better, which is why I wrote a function that takes any number of arguments, converts them to strings, adds them to a stringstream and prints that stream. My expectation would have been that the compiler jumps from \\1
to \\2
to \\3
to \\4
to \\5
(compare code). But instead, it is stuck at \\2
. Why is that?
Should the compiler not take the case that is "most matching" for a function invocation? My understanding of variadic templates is that you go from top to bottom and from base case to exception. I would have expected that, in \\2
, when print(strs, "this", " is ", "a ", "test ", 1, 2, 'a')
is called that this would go to \\3
.
#include <string>
#include <iostream>
#include <sstream>
void print(std::string msg) // 5
{
std::cout << msg;
}
template <class T>
void print(std::stringstream &strs, T t) // 4
{
strs << std::to_string(t);
print(strs.str());
}
template <class... Args, class T>
void print(std::stringstream &strs, T t, Args... args) // 3
{
strs << t;
print(strs, args...);
}
template <class... Args>
void print(Args... args) // 2
{
std::stringstream strs();
print(strs, args...);
}
int main()
{
print("this", " is ", "a ", "test ", 1, 2, 'a'); // 1
}
Vexing parse with:
std::stringstream strs();
Function declaration
Use
std::stringstream strs{};
or
std::stringstream strs;