Thanks, all, @TedLyngmo told me what I did wrong. I cannot overload operator << for standard types, so, I needed to create a class and use it instead to unpack my template parameters. Here's a sample code that works, again, patterned from that Vandervoode, Josuttis and Gregor book:
#include <iostream>
#include <string>
template<typename T>
class AddSpace
{
private:
T const& ref;
public:
AddSpace(T const& r) : ref(r) {}
friend std::ostream& operator << (std::ostream& str, AddSpace<T> s)
{
return str << s.ref << ' ';
}
};
template <typename... Args>
void print(Args... args)
{
// Fold expression unpacks args, creates one AddSpace object per arg, and outputs each AddSpace::ref to std::cout.
(std::cout << ... << AddSpace(args)) << std::endl;
}
int main()
{
print(1, 2, 3, 4);
return 0;
}
Creating a user class, overloading operator << to take values from that class, and using it to unpack the template parameters, apparently does the job. It's a bit complicated but it works. So, again, thanks to you all!