Better cout a.k.a coutn; - c++

Guys would it be difficult to write coutn which would basically place newline symbol at the end of the input. While working with console (that's all I can do at the moment) I'm finding very tedious to write '\n' every time I want the line to be a new line.
Or maybe it is already implemented?

To circumvent the multiple injections on a single line, you could use a temporary object. This temporary object would add the '\n' in its destructor.
struct coutn {
coutn(): os(cout) {}
~coutn() { os << '\n'; }
template <typename T>
coutn & operator<<(T const & x) { os << x; return *this; }
private:
ostream &os;
};
coutn() << "Hello " << "World" << "!";
In the end, I'm wondering if this coutn is actually better?

Well, the first obvious thing would be to implement some kind of wrapper around it:
class Print
{
public:
explicit Print(std::ostream& stream = std::cout): mStream(stream) {}
~Print() { mStream << '\n'; }
template <class T>
Print& operator<<(T const& t) { mStream << t; return *this; }
private:
std::ostream& mStream;
};
Usage is like such:
int main(int argc, char* argv[])
{
Object object;
Print() << "My new object value: " << object;
std::ofstream file("file.log");
Print(file) << "My new object value: " << object;
}
Easy, Peasy.

Roughly:
struct StreamFilterN
{
ostream & os;
StreamFilterN(ostream & os_) : os(os_) {}
template <typename T>
StreamFilterN & operator<<(T const & x) { os << x << "\n"; return *this; }
}
StreamFilterN coutn(cout);
coutn << "Hello world";
coutn << "Yeah, like.";
(I'm not sure if this works perfectly, but it should get you started)

The way that streams work is that they add one thing and then return itself.
so are you sure you'd want to do what you're asking?
For example:
s << "a" << "b";
Would put:
a
b
Surely you can find a way with some kind of wrapper but the extra overhead incurred and the diminished code readability I don't think is worth it. Most coders are familiar with standard C++. Most coders are not familiar with your coutn and how it works.

Come one people. You must admit that C++'s newlines are too verbose. Look at C#, D, Java, Python, Ruby, should I go on? I don't think you should implement a coutn. I think you'd be better off following D's example with write, writeln, writef, and writefln variadic template functions.
Anyway here is how to do it without macros and with out needing to explicitly create temporaries.
class coutn_t
{
private:
class newliner
{
public:
explicit newliner(std::ostream & out=std::cout) : m_out(out) { }
template<typename T>
newliner& operator<<( const T& t)
{
m_out << t;
return *this;
}
~newliner() { m_out << std::endl; }
private:
std::ostream & m_out;
};
public:
// NOTE: these return by value. Only one newliner will be
// destructed however as RVO will eliminate the copy.
newliner operator()( std::ostream& out )
{ return newliner(out); }
template< typename T >
newliner operator<<( const T& t )
{
std::cout << t;
return newliner(std::cout);
}
};
coutn_t coutn;
coutn << "Hello World!";
coutn << "Hello " << "World" << '!';
std::ofstream file("ouput.txt");
coutn(file) << "Hello World" << " via file";
The complete solution will have to add more overloads for operator<< to handle stream manipulators (std::hex etc). The functions returning newliners must always be inline to allow RVO.

Related

Narrowing down a C++ concept to exclude certain types

Suppose I would want to overload the left shift operator for ostreams and all containers.
This is what I'm currently have (compile with -fconcepts):
#include <vector>
#include <iostream>
template<typename Container>
concept bool Iterable = requires(Container t) {
{ *t.begin()++, t.end() };
};
template<Iterable T>
std::ostream& operator<<(std::ostream& out, const T& t) {
for(const auto& it: t) {
out << it << " " ;
}
return out;
}
int main() {
std::vector<int> a = {1, 2, 3};
std::cout << a << std::endl;
std::string str = "something";
// std::cout << str << std::endl; // compile error if the template is defined
return 0;
}
The problem however, is that this there is already a version of the ostream&<< for std::string.
Is there a general (something like a requires not expression) or specific (maybe similar to partial specialization by which I can exclude concrete classes) way to exclude something in a concept?
If not, what is the correct way around this?
template<Iterable T>
requires !requires(std::ostream o, T a) { operator<<(o, a); }
std::ostream& operator<<(std::ostream& out, const T& t) {
for(const auto& it: t) {
out << it << " " ;
}
return out;
}
Add a requirement that the type does not already have an operator<< defined. I am not 100% sure this should work, but it does work on gcc.
(simply o << a crashes gcc)

operator << overloading in a constructor

I'm debugging a program and I would like to make printing from that pattern:
std::cout << firstVar << ", " << secondVar << ", " << thirdVar << endl ;
shorter, i.e, the same thing should happen if we will write the code:
shortPrint(std::cout) << firstVar << secondVar << thirdVar;
note: there is no limit for the variables quantity, it can be 1 and it can be 20, so that should also work:
shortPrint(std::cout) << firstVar << secondVar << thirdVar << anotherVar << oneMoreVar;
Someone told me that the easiest wat to do that is to create class that is called "shortPrint".
Can anyone help me figuring this out?
For start, I would say that I only need to implement a constructor and operator << overloading, but I'm not sure how to do that exactly in that case.
Yes create a shortPrint class with an appropriate overloaded operator. Something like this :
class shortPrint {
ostream &o;
public:
shortPrint(ostream &o) : o(o) {}
template <typename T> shortPrint &operator<<(const T &t) {
o << t << ',';
return *this;
}
// support for endl, which is not a value but a function (stream->stream)
shortPrint &operator<<(ostream& (*pf)(std::ostream&)) {
o << pf;
return *this;
}
};
That should work (basically).
To eliminate the problem of extra commas use this :
class shortPrint {
class shortPrint2{
shortPrint &s;
public:
shortPrint2(shortPrint &s) : s(s) {}
template <typename T> shortPrint2 &operator<<(const T &t) {
s.o << ',' << t ;
return *this;
}
shortPrint &operator<<(ostream& (*pf)(std::ostream&)) {
s.o << pf;
return s;
}
};
ostream &o;
shortPrint2 s2;
public:
shortPrint(ostream &o) : o(o), s2(*this) {}
template <typename T> shortPrint2 &operator<<(const T &t) {
o << t;
return s2;
}
shortPrint &operator<<(ostream& (*pf)(std::ostream&)) {
o << pf;
return *this;
}
};
You can do something like the following:
class _ostream_wrap
{
public:
template <class T>
_ostream_wrap& operator << (const T & v)
{
m_ost << "[ " << v << " ]";
return (*this);
}
explicit _ostream_wrap(std::ostream & ost)
:m_ost(ost)
{}
private:
std::ostream& m_ost;
};
template <class OSTREAM>
_ostream_wrap shortPrint(OSTREAM & o)
{
return _ostream_wrap(o);
}
//...
shortPrint(std::cout) << 1 << 2;
however this implementation will not work on rvalues:
//you can't do something like the following:
shortPrint(MyOstream(some_args)) << 1;
This is because the class _ostream_wrap keeps a reference to the stream and for rvalues case it needs to make a copy. To make a copy you need to have two implementations (this would be the final version):
template <class OSTREAM>
class _ostream_wrap
{
public:
template <class T>
_ostream_wrap<OSTREAM>& operator << (const T & v)
{
m_ost << "[ " << v << " ]";
return (*this);
}
public:
//the constructor is harder to write so i decided
//that for this i will keep the member public
OSTREAM m_ost;
};
template <class OSTREAM>
_ostream_wrap<OSTREAM&> shortPrint(OSTREAM & o)
{
_ostream_wrap<OSTREAM&> rvalue;
rvalue.m_ost = o;
return rvalue;
}
template <class OSTREAM>
_ostream_wrap<OSTREAM> shortPrint(const OSTREAM & o)
{
_ostream_wrap<OSTREAM> rvalue;
rvalue.m_ost = o;
return rvalue;
}
Here's something with very basic functionality:
#include <iostream>
struct shortPrint {
explicit shortPrint(std::ostream& os)
: strm(&os), first(true) {}
template<typename T>
shortPrint& operator<<(T&& t)
{
if (first) {
first = false;
} else {
*strm << ", ";
}
*strm << std::forward<T>(t);
return *this;
}
shortPrint& operator<<( std::ostream& (*func)(std::ostream&) )
{
*strm << func;
return *this;
}
private:
std::ostream* strm;
bool first;
};
int main()
{
int i = 3;
shortPrint(std::cout) << "1" << 2 << i << std::endl;
shortPrint(std::cout) << 4;
}
The tricky part is getting the commas to be printed correctly. I chose to print them before every streamed object, except before the very first one. As you can see, there's one general operator<< template that simply prints the comma and forwards the argument. The next problem are stream manipulators, because we don't want to print commas before them. The other operator<< overload takes care of that. If you want to be more generic, there's two more you need to take care of (see no. 9 here ).
Hope that helps.
Return the ostream from the function. Something like:
std::ostream &shortPrint(std::ostream &out) {
//whatever you need here
return out;
}
Edit: you the kind of formatting you need, you need to make a class with overloaded stream operator that returns the class. But you need to keep the reference to the needed stream in the class.

Write a simple Function that works like "std::cout" but adds a Line Break at the End

In C++ there is a standard library function called cout, which lets me send text to the console. I am sure you know that.
#include <iostream>
using std::cout;
cout << "Some Text " << 15 << " Other Text";
To do a linebreak at the end, I need to use endl.
cout << "Some Text " << 15 << " Other Text" << endl;
How can I write a function named coutl which behaves like cout but also adds a likebreak? I want to use the same syntax that cout uses, especially the << operator.
coutl << "Some Text " << 15 << " Other Text"; // coutl should add a linebreak
By creating a little proxy object which adds << endl in its destructor:
class AddEndl
{
public:
AddEndl(std::ostream& os) : _holder(new Holder(os)) {}
template <class T>
friend std::ostream& operator<< (const AddEndl& l, const T& t)
{
return (l._holder->_os) << t;
}
private:
struct Holder {
Holder (std::ostream& os) : _os(os) {}
~Holder () { _os << std::endl; }
std::ostream& _os;
};
mutable std::shared_ptr<Holder> _holder;
}
Then you need a function so that you will get a temporary:
AddEndl wrap(std::ostream& os)
{
return AddEndl(os);
}
This should then work:
wrap(std::cout) << "Hello";
UPDATE:
I move the destructor which adds a std::endl to an inner object owned by a std::shared_ptr<> so that the example doesn't depend on Copy Elision anymore.
Not possible with just a non-temp object created on the stack & which has full function scope. How will the object ever know what this is the last of the chained calls to the << operator?
You can try hacks like these
class coutl
{
public:
~coutl()
{
cout<<endl;
}
template<class T>
coutl &operator<<(const T &x)
{
cout<<x;
return *this;
}
};
int main()
{
coutl()<<"Hello"<<10<<"World";
coutl()<<"Hello"<<20<<"World";
}
Another similar hack using the destructor
class myostream
{
public:
~myostream()
{
cout<<endl;
}
template<class T>
myostream &operator<<(const T &x)
{
cout<<x;
return *this;
}
};
int main()
{
{
myostream coutl;
coutl<<"Hello"<<10<<"World";
}
{
myostream coutl;
coutl<<"Hello"<<10<<"World";
}
}
In fact the code
cout << "Some Text " << 15 << " Other Text" << endl;
calls the operator function(s)
// (pseudo code)
std::ostream& operator<<(std::ostream, [type] obj);
several times for each use of the << operators.
To achieve what you want you would need to create a class that behaves like std::ostream, but 'magically' knows when the 'last' call to operator<< is issued and appends a linebreak. That's not possible IMHO without another object that keeps track of the statements scope.
coutl << "Some Text " << 15 << " Other Text"; // coutl should add a linebreak
Your idea can't be realize. In fact, cout << str1; is equivalent to cout.operator<<(str1) which returns a reference of cout itself. So cout << a << b << c; can be resolvd to ((cout << a) << b) << c; It doesn't know when is the last call to insert an linebreak.

C++ Wrap cin and cout in class - Overload << and >> operators

I am trying to make a Console class. I would like to wrap cin and cout in the class and overload the << and >> operators. So I could use the class as such:
// Output
Console << "Call cout from Console" << endl;
// Input
string str;
Console >> str; // Call cin
My best guess was:
class Console {
//...
public:
ostream& operator<< (ostream& os)
{
cout << os;
return &cout;
}
//...
};
But I know that's wrong, how could I overload the operators to use the Console class as both cin and cout?
I got a working code that can handle the stream manipulators. You can see my code in action in this Ideone page
Here is the code:
#include <iostream>
typedef std::ostream& (*manip) (std::ostream&);
class console {
};
template <class T> console& operator<< (console& con, const T& x) { std::cout << x; return con; }
template <class T> console& operator>>(console& con, T& x) { std::cin >>x; return con; }
console& operator<< (console& con, manip manipulator){ std::cout<<manipulator; return con;}
int main() {
console c;
int a,b;
c>>a>>b;
c << "hello world"<<std::endl<<std::hex<<(a+b)<<std::endl;
}
Thanks #MooingDuck for the discussion that led me to a working answer and #111111 for the start point.
I don't know why would want to do such a thing but it isn't the stream you need to capture but the other type. But if this is just to make std::cout and std::cin more convenient I wouldn't bother.
class console {
};
template<typename T>
console& operator<<(console con, const T& val) {
std::cout << val;
return con;
}
console c;
c << "hello world\n";
This is not direct answer to your question, but maybe I point you out some alternative.
See my answer to some other question. To define yourself all of these <<and >> operators is not very easy. However you can overwrite streambuf for Console. Use combined streambufs of cin and cout,
Derive your console from std::iostream and your streambuf from std::streambuf
class console_streambuf : public std::streambuf {
public:
console_streambuf() {
// no buffering, overflow on every char
setp(0, 0);
}
virtual int_type overflow(int_type c) {
std::cout << c;
return c;
}
...
};
class console : public std::iostream {
public:
console() { rdbuf(&buf); }
private:
console_streambuf buf;
};
Contrary to many of the answers above, doing what you want is pretty simple, using the magic of templates.
I'd recommend using a stringstream, because using an ostream (cout is an ostream) can require arcane black magic (no joke).
#include <string>
#include <iostream>
#include <sstream>
struct console {
std::stringstream data_;
console() : data_() { };
// We make ourselves a template sink so we can "take" operator<<'s.
// The awesome advantage to using a template like this is that the
// compiler will allow us to "take" any data that can be converted
// to a stringstream, which will handle converting int's etc.
// for us!
template<typename T>
console& operator<<(const T& what) {
data_ << what;
return *this; // We must return a reference if we want to
// string together more than one thing, i.e.
// b << " " << 4;
}
void flush() {
std::cout << data_.str();
data_.clear();
std::cout.flush();
}
};
int main()
{
int a = 4;
console b;
console c;
b.data_ << 2;
c.data_ << 4;
//b << std::cout; // WHAT? it's possible but stupid, prints garbage
// Because we made the template return a reference, this will
// allow us to chain things just like we do with cout.
b << " HELLO WORLD! " << "yo!" << 4;
b << a << " " << 4.2f;
// Compiler chokes on this. It will try to convert "console"
// to a stringstream which it can't.
//b << c;
b.flush(); // Send out the output
// Wait for key press
char foo[500];
gets(foo);
}
Output:
2 HELLO WORLD! yo!44 4.2
Just like cout, except of course with more control.
You can get into using basic_ostream's and basic_istreams if you want binary I/O, but I'd recommend against it unless you really really need it.
Overloaded operator functions must be declared with the specific types you're going to call them with on the left and right. So you will need an operator<< (int), operator<< (double), operator<< (const std::string &), etc.
If you're really just going to pass them on to cin and cout, you can save typing by using a template member function, like:
template <class T> Console& operator<< (const T& x) { cout << x; return *this; }
[thanks to André for pointing out it should return Console& so you can string together calls like Console << a << b; ]

Have a C++ Class act like a custom ostream, sstream

I have a C++ class MyObject and I want to be able to feed this data like I would to a osstream (but unlike a direct sstream, have the incoming data be formatted a special way). I can't seem to figure out how to overload a operator for MyObject to eat input given to it.
class MyObject {
public:
ostringstream s;
FEEDME
};
int main() {
MyObject obj;
obj.FEEDME << "Hello" << 12345;
// I want obj.s == ":Hello::12345:"
}
I want it so every item fed in be surrounded by : :
So in the given example, s = ":Hello::12345" should be the final outcome. What my question is, how can I tell the object that when ever a <<something, put : : around the something.
Is this possible?
try this:
class MyObject {
public:
template <class T>
MyObject &operator<<(const T &x) {
s << ':' << x << ':';
return *this;
}
std::string to_string() const { return s.str(); }
private:
std::ostringstream s;
};
MyObject obj;
obj << "Hello" << 12345;
std::cout << obj.to_string() << std::endl;
There are certain things you won't be able to shove into the stream, but it should work for all the basics.
You may find the answers for How do I create my own ostream/streambuf? helpful.
I would take a slightly different approach and create a formater object.
The formater object would then handle the inserting of format character when it is applied to a stream.
#include <iostream>
template<typename T>
class Format
{
public:
Format(T const& d):m_data(d) {}
private:
template<typename Y>
friend std::ostream& operator<<(std::ostream& str,Format<Y> const& data);
T const& m_data;
};
template<typename T>
Format<T> make_Format(T const& data) {return Format<T>(data);}
template<typename T>
std::ostream& operator<<(std::ostream& str,Format<T> const& data)
{
str << ":" << data.m_data << ":";
}
int main()
{
std::cout << make_Format("Hello") << make_Format(123);
}