I don't understand why this doesn't work. Could someone who understands templates and variadic expression folding explain what is going on and give a solution that does work?
#include <iostream>
#include <string>
template <typename... Args>
void print(Args... args)
{
std::string sep = " ";
std::string end = "\n";
(std::cout << ... << sep << args) << end;
}
int main()
{
print(1, 2, 3);
}
It should print out each of the args with a space in between and a newline at the end. It works if you remove the sep <<
but then there is no space between each argument when it is printed.
The grammar for binary fold-expressions must be one of:
(pack op ... op init)
(init op ... op pack)
What you have is (std::cout << ... << sep << args)
, which doesn't fit either form. You need something like (cout << ... << pack)
, which is why removing sep
works.
Instead, you can either fold over a comma:
((std::cout << sep << args), ...);
or use recursion:
template <class A, class... Args>
void print(A arg, Args... args) {
std::cout << arg;
if constexpr (sizeof...(Args) > 0) {
std::cout << sep;
print(args...);
}
}