Search code examples
c++recursionprintingvariadic-templates

Why is my recursive variadic template not compiling?


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.

Play with this code.

#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
}

Solution

  • Vexing parse with:

    std::stringstream strs(); Function declaration

    Use

    std::stringstream strs{};

    or

    std::stringstream strs;

    Demo