I am trying to make a flow manipulator for color for use with console output. It works by changing the color of text and background:
std::cout << ConColor::Color::FgBlue << 123 << "abc";
The problem is the signature:
std::ostream &FgBlue(std::ostream &);
This signature also allows you to use derived classes such as std::ostringstream , but there is no way to change the color of the string stream. The function will change the color of the console regardless of whether it was called with this argument.
So I want the argument to be something like std::cout , std::wcout , etc. I would prefer it to be generic if more std::ostream objects are added to the next standard.
I tried a lot of things related to std::is_same and std::is_base_of when the first one didn't work, just to make it senseless, because any type of argument inheriting from std::basic_ostream<> will be passed to the type I'm comparing with when the function is passed, giving false positives.
This ultimately led me to my answer below (template variational template arguments: “Wow, this is a sip!”) There are several problems:
- The compiler must support variable templates. I would prefer the solution to work on MSVC.
- The compiler gives critical errors when using a derived class with a different number of template arguments (for example,
std::ostringstream , which has 3 instead of 2), since it does not pass by the signature of the function. - You can redirect stdout, say, to a file, so even if the argument is
std::cout , the same thing happens as with a string stream.
I urge people to post any other solutions, hopefully better than mine, and really hope something that works, at least with VS11.
source share