I'd like to wrap std::cout
for formatting, like so:
mycout([what type?] x, [optional args]) {
... // do some formatting on x first
std::cout << x;
}
and still be able to use expressive syntax like
mycout("test" << i << endl << somevar, indent)
instead of being forced to be more verbose like
mycout(std::stringstream("test") << i ...)
How can I implement this? What type to make x
?
Edit: added consideration for optional arguments
How about this:
struct MyCout {};
extern MyCout myCout;
template <typename T>
MyCout& operator<< (MyCout &s, const T &x) {
//format x as you please
std::cout << x;
return s;
}
And put MyCout myCout;
into any one .cpp file.
You can then use myCout
like this:
myCout << "test" << x << std::endl;
And it will call the template operator<<
which can do the formatting.
Of course, you can also provide overloads of the operator for special formatting of specific types if you want to.
EDIT
Apparently (thanks to @soon), for standard manipulators to work, a few more overloads are necessary:
MyCout& operator<< (MyCout &s, std::ostream& (*f)(std::ostream &)) {
f(std::cout);
return s;
}
MyCout& operator<< (MyCout &s, std::ostream& (*f)(std::ios &)) {
f(std::cout);
return s;
}
MyCout& operator<< (MyCout &s, std::ostream& (*f)(std::ios_base &)) {
f(std::cout);
return s;
}
EDIT 2
I may have misunderstoor your original requirements slightly. How about this (plus the same manipulator overloads as above):
struct MyCout
{
std::stringstream s;
template <typename T>
MyCout& operator << (const T &x) {
s << x;
return *this;
}
~MyCout() {
somehow_format(s);
std::cout << s.str();
}
};
int main() {
double y = 1.5;
MyCout() << "test" << y;
}
This comes easy with variadic template arguments:
template <class T>
void print(T t)
{
std::cout << t;
}
template <class T, class... Args>
void print(T t, Args... args)
{
std::cout << t << std::endl;
print(args...);
}
int main()
{
std::cout << std::boolalpha;
print(3, 's', true, false);
}
Output:
3
s
true
false
Live Demo
A variation from the answers:
#include <iostream>
using namespace std;
class MyCout
{
public:
MyCout& operator()(bool indent) {
if ( indent ) cout << '\t';
return *this;
}
template<class T>
MyCout& operator<<(T t) {
cout << t;
return *this;
}
MyCout& operator<<(ostream& (*f)(ostream& o)) {
cout << f;
return *this;
};
};
int main()
{
MyCout mycout;
int x = 10;
mycout(true)<< "test" << 2 << x << endl ;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With