Reputation: 101
So far, I have a function print:
template < char Sep = ' ', class... Args >
void print(Args&&... args)
{
([](Args&& arg)
{
std::cout << arg << Sep;
}(std::forward<Args>(args)), ...);
std::cout << '\n';
}
int main()
{
print("a", 'b', 3, 4.0, 5.0f, true);
}
I want to template it on std::ostream so that I can print to the buffer I want but I am struglling. Here is what I tried (I have put errors as comment in the code):
//Error: a nontype parameter may not have class type
template < std::ostream os, char Sep = ' ', class... Args >
void print(Args&&... args){ /*omitted code */ os << arg << Sep; }
int main()
{
print("a", 'b', 3, 4.0, 5.0f, true);
}
I though maybe I could use a class to work-around the problem:
template < class Buffer >
class Printer
{
public:
void Set(Buffer* buff)
{
this->buff = buff;
}
//Error: the usage of 'Printer<std::ostream>::buff' requires the compiler
//to capture this but the current default capture mode does not allow it
template < char Sep = ' ', class... Args >
void operator()(Args&&... args)
{
([](Args&& arg)
{
(*buff) << arg << Sep;
}(std::forward<Args>(args)), ...);
std::cout << '\n';
}
private:
Buffer* buff;
};
int main()
{
Printer<std::ostream> print;
print.Set(&std::cout);
print("a", 'b', 3, 4.0, 5.0f, true);
}
Upvotes: 0
Views: 171
Reputation: 123084
Use an ordinary template argument and pass the stream as parameter to the function:
#include <iostream>
template <typename stream, char Sep = ' ', class... Args >
void print(stream& out,Args&&... args)
{
([&out](Args&& arg)
{
out << arg << Sep;
}(std::forward<Args>(args)), ...);
std::cout << '\n';
}
int main()
{
print(std::cout,"a", 'b', 3, 4.0, 5.0f, true);
}
If only std::ostream
s are ok you need not make it a template, but simply use an std::ostream&
argument. The standard library makes use of inheritance only sparingly, but for streams there are base classes that can be used when you want to use standard streams.
PS: As pointed out by MarekR you do not need the lambda. The function is simpler like this:
#include <iostream>
template <typename stream, char Sep = ' ', class... Args >
stream& print(stream& out,Args&&... args)
{
return ((out << args << Sep) , ...) << '\n';
}
int main()
{
print(std::cout,"a", 'b', 3, 4.0, 5.0f, true);
}
Upvotes: 3