Buffer flushing in ostream overloading - c++

What is the recommended way to use buffer flushing when overloading ostream in C++? Do I just disable buffer flushing in the beginning and enable it in the end? If so should i flush the buffer before returning the ostream? I have never seen this part mentioned in any ostream overloading reference.
EDIT: Lets say i have a class with a lot of members. The ostream operator prints each member. How should i write the ostream overload?
struct ToPrint {
char firstMember;
char secondMember;
int number;
};
std::ostream& operator<<(std::ostream& os, const ToPrint& instance) {
os << instance.firstMember << '\n'
<< instance.secondMember << '\n';
if (instance.number > 0)
os << instance.number << '\n';
return os;
}

The recommended use of buffer flushing for output streams in C++ is to not do it. Unless you have special requirements, the default behavior of the stream will work just fine.

Related

Overloading << for both iostream and fstream

I am trying to overload both cout from iostream and fout from fstream
ostream& operator<<(ostream& cout, const Object& obj);
ofstream& operator<<(ofstream& fout, const Object& obj);
I want the first function to work with the console so have text for the user while I want the second function to only output the value of the variables onto a file.
However, in
void save_data(const Object& obj)
{
fstream fout("DataBase.txt", ios::out);
if (fout.is_open())
{
fout << obj;
fout.close();
}
else
cout << "DataBase.txt could not be saved!" << endl;
}
I have text that I used to guide the user inside my function that overloads cout in my file.
std::fstream inherits from std::iostream, which in turn inherits from std::ostream. There's no std::ofstream in that chain, making that overload an unsuitable candidate.
One way to fix this is to use std::ofstream at the callsite instead of std::fstream. You can also add an overload for std::fstream. However, be aware that std::ostream is not necessarily the console; that's a guarantee you have to provide yourself from the rest of the code. For example, a std::ofstream could be upcast to std::ostream and then used to print an Object and your overload set would assume this stream is for the console. It might be hard to ensure the rest of your code provides that guarantee. In addition, robust detection of a console is going to be platform-dependent with its own answers elsewhere on the site (e.g., for Windows).
One way that existing programs handle this requirement is to have an explicit "interactive" option on the command line. For example, git commands use --interactive and sometimes -i for this purpose. This way, the user asks for the extra guiding output and there's no clever detection trickery required.
Thanks to the help from #chris I was able to figure out what the real problem was. Normally one doesn't need to overload based on the base and derived I/O stream types. There's usually a polymorphic way to do what you want. In this case you can check if the stream being written to is std::cout and construct a new stream with a buffer to write to it.
std::ostream& operator<<(std::ostream& os, Obj const& obj) {
std::ostream o(nullptr);
if (&os == &std::cout) {
o.rdbuf(std::cout.rdbuf());
}
o << "hello\n";
return os;
}
Writing to o will do nothing if the buffer is a null pointer. This will allow you to write your console output guides for the user without separating both implementations.
If you would still like to split the implementations, create two functions and call the appropriate one when the above if condition is true and false.
std::ostream& write_with_console_o(std::ostream&);
std::ostream& write_with_file_o(std::ostream&);
std::ostream& operator<<(std::ostream& os, Obj const& obj) {
if (&os == &std::cout) {
return write_with_console_o(os);
}
return write_with_file_o(os);
}

Obscure C++ operator overloading

I have the following code:
#include <iostream>
using namespace std;
ostream& f(ostream& os) {
return os << "hi";
}
int main() {
cout << "hello " << f << endl;
return 0;
}
And somehow this works - the output is "hello hi". How does this get interpreted by the compiler? I don't understand how a function can be inserted into a stream.
std::ostream has an operator<< overload that receives a pointer to a function with the signature such as the one you wrote (number 11 in this list):
basic_ostream& operator<<(
std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&) );
which just calls the given function passing itself as argument. This overload (along with several similar others) is there to allow you to implement stream manipulators, i.e. stuff that you output in the stream with an << and changes the state of the stream from there. For example, our version of the (incorrectly) ubiquitous std::endl may be implemented as
std::ostream &myendl(std::ostream &s) {
s<<'\n';
s.flush();
return s;
}
which can then be used exactly as the "regular" std::endl:
std::cout<<"Hello, World!"<<myendl;
(the actual implementation is templated and a bit more complicated because it has to work even with wide streams, but you got the idea)
std::ostream::operator<< has an overload which accepts a function as parameter; and the body of that overload is to invoke the function given.
This is exactly how endl works in fact. endl is actually a function similar to:
ostream &endl(ostream &os)
{
os << '\n';
os.flush();
return os;
}

what's the best practice to print out(print debugging information) for a class?

I am wondering what's the best practice to print out a class (say classA), I have several method
classA ca;
1) Define a debug method and inside this method , print out all its members.
2) Define a str() method, and use cout<< ca.str()
3) Define something like string conversion(I am not sure how yet), and just use cout << ca
The usual way is to overload operator<< roughly like this:
std::ostream &operator<<(std::ostream &out, classA const &a) {
// precise formatting depends on your use case. Do the same thing you would
// if you wanted to print a to cout or a file, because that is what this code
// will end up doing.
out << a.some_data() << ", " << a.some_more_data();
return out;
}
If classA has a limited interface (does not expose all relevant data members), it may be necessary to make the operator<< a friend of classA, such as
class A {
public:
// stuff
friend operator<<(std::ostream &out, classA const &a);
};
// private members can then be accessed
std::ostream &operator<<(std::ostream &out, classA const &a) {
out << a.some_private_member << ", " << a.some_other_private_member;
return out;
}
There is not usually a good reason to prevent read access to private members that you then enable the user to dump out per operator<<, though, since it would be rather leaky access control.
This then enables you to write
classA a;
std::cout << a;
std::ofstream file("foo.txt");
file << a;
std::ostringstream fmt;
fmt << a;
std::string s = fmt.str();
and so forth.
As a style note: It is possible to write
std::ostream &operator<<(std::ostream &out, classA const &a) {
// precise formatting depends on your use case
return out << a.some_data() << ", " << a.some_more_data();
}
This achieves the same thing as the split return because operator<< (by convention) returns the same stream object that was passed into it (to enable the chaining of << as in std::cout << i << j << k;).
Style note 2: If there is nothing in classA that makes it difficult, an upgrade to this technique is to write
template<typename char_type>
std::basic_ostream<char_type> &operator<<(std::basic_ostream<char_type> &out, classA const &a) {
// rest as before. Put it in a header because it is a function template now.
}
This enables you to write classA objects not only to cout, cerr, clog, ofstream, ostringstream etc., but also to their wchar_t counterparts wcout, wcerr, wclog, wofstream, and wostringstream. These are rarely used in practice, but often it will cost you nothing to implement this feature. The trick is that std::ostream and std::wostream -- base classes of all these output streams -- are aliases for std::basic_ostream<char> and std::basic_ostream<wchar_t>, respectively. That gives us this nice way to handle both (and potentially other) character classes without code duplication.
clog can be an option if you want to log your steps of a process in some file and review the file later to see what goes wrong. Also you can check state of data members at certain interval by logging them externally in file.

operator overloading

How can I overload << operator (cout) so that it can be written to a file. Whenever << occurs it should be appended to the file i.e. instead of displaying on the screen it should be written to the file.
can i get a code for this...i am new to c++ and code written by me is not working..
Normally you provide std::ostream& operator<<(std::ostream&, const YourClass&) for your class and write to a file stream as follows:
std::ofstream ofs("out");
ofs << yourObject;
where yourObject is an object of YourClass.
Your overloaded << operator shouldn't care what kind of output stream that it goes to or whether it's appending or overwriting. It takes a std::ostream& and writes to it. If it's used with cout, then it's written to the console. If it's used with a std::ofstream, then it writes to a file. If that std::ofstream was opened to overwrite, then it overwrites. If it was opened to append, then it appends.
All that your overloaded << operator should care about is that it's writing to an output stream. What that stream represents is irrelevant.
This overloading is already done for the C++ file stream. The name cout means console out and the spirit is, it will output to console.
One thing you could do is use freopen(), to redirect all output to a file.
If you just want to send text to a file rather than the console, then std::ofstream is your friend. Like cout, your instance of ofstream shares the behaviour of ostream which already has a suitable << operator for strings and can be used exactly as cout. Here's an example:
#include <fstream>
int main()
{
std::ofstream fout("somefile.txt");
fout << "Some text" << std::endl;
return EXIT_SUCCESS;
}
Compile and run and you'll find that you have a new file in the current working directory:
% cat somefile.txt
Some text
If you need to stream an object that doesn't have operator << overloaded for std::ostream, then you you will need to overload the operator, like this:
std::ostream& operator <<(std::ostream& os, const SomeClass& instance)
{
instance.print(os);
return os;
}
You'll need void SomeClass::print(std::ostream& os) defined to send its private data to os (this saves you making the << a friend of your class).
Were you talking purely about cout, then this isn't "operator overloading", this is stream redirection. But, yes, it is possible (too) by setting the associated stream buffer using std::basic_ios::rdbuf().
Here is my solution from "Redirecting in C++":
#include <iostream>
#include <fstream>
class scoped_cout_redirector
{
public:
scoped_cout_redirector(const std::string& filename)
:backup_(std::cout.rdbuf())
,filestr_(filename.c_str())
,sbuf_(filestr_.rdbuf())
{
std::cout.rdbuf(sbuf_);
}
~scoped_cout_redirector()
{
std::cout.rdbuf(backup_);
}
private:
scoped_cout_redirector();
scoped_cout_redirector(const scoped_cout_redirector& copy);
scoped_cout_redirector& operator =(const scoped_cout_redirector& assign);
std::streambuf* backup_;
std::ofstream filestr_;
std::streambuf* sbuf_;
};
int main()
{
{
scoped_cout_redirector file1("file1.txt");
std::cout << "This is written to the first file." << std::endl;
}
std::cout << "This is written to stdout." << std::endl;
{
scoped_cout_redirector file2("file2.txt");
std::cout << "This is written to the second file." << std::endl;
}
return 0;
}

C++ stream as a parameter when overloading operator<<

I'm trying to write my own logging class and use it as a stream:
logger L;
L << "whatever" << std::endl;
This is the code I started with:
#include <iostream>
using namespace std;
class logger{
public:
template <typename T>
friend logger& operator <<(logger& log, const T& value);
};
template <typename T>
logger& operator <<(logger& log, T const & value) {
// Here I'd output the values to a file and stdout, etc.
cout << value;
return log;
}
int main(int argc, char *argv[])
{
logger L;
L << "hello" << '\n' ; // This works
L << "bye" << "alo" << endl; // This doesn't work
return 0;
}
But I was getting an error when trying to compile, saying that there was no definition for operator<< (when using std::endl):
pruebaLog.cpp:31: error: no match for ‘operator<<’ in ‘operator<< [with T = char [4]](((logger&)((logger*)operator<< [with T = char [4]](((logger&)(& L)), ((const char (&)[4])"bye")))), ((const char (&)[4])"alo")) << std::endl’
So, I've been trying to overload operator<< to accept this kind of streams, but it's driving me mad. I don't know how to do it. I've been loking at, for instance, the definition of std::endl at the ostream header file and written a function with this header:
logger& operator <<(logger& log, const basic_ostream<char,char_traits<char> >& (*s)(basic_ostream<char,char_traits<char> >&))
But no luck. I've tried the same using templates instead of directly using char, and also tried simply using "const ostream& os", and nothing.
Another thing that bugs me is that, in the error output, the first argument for operator<< changes, sometimes it's a reference to a pointer, sometimes looks like a double reference...
endl is a strange beast. It isn't a constant value. It's actually, of all things, a function. You need a special override to handle the application of endl:
logger& operator<< (logger& log, ostream& (*pf) (ostream&))
{
cout << pf;
return log;
}
This accepts insertion of a function that takes an ostream reference and returns an ostream reference. That's what endl is.
Edit: In response to FranticPedantic's interesting question of "why can't the compiler deduce this automatically?". The reason is that if you delve yet deeper, endl is actually itself a template function. It's defined as:
template <class charT, class traits>
basic_ostream<charT,traits>& endl ( basic_ostream<charT,traits>& os );
That is, it can take any sort of ostream as its input and output. So the problem isn't that the compiler can't deduce that T const & could be a function pointer, but that it can't figure out which endl you meant to pass in. The templated version of operator<< presented in the question would accept a pointer to any function as its second argument, but at the same time, the endl template represents an infinite set of potential functions, so the compiler can't do anything meaningful there.
Providing the special overload of the operator<< whose second argument matches a specific instantiation of the endl template allows the call to resolve.
endl is an IO manipulator, which is a functor that accepts a stream by reference, performs some operation on it, and returns that stream, also by reference. cout << endl is equivalent to cout << '\n' << flush, where flush is a manipulator that flushes the output buffer.
In your class, you just need to write an overload for this operator:
logger& operator<<(logger&(*function)(logger&)) {
return function(*this);
}
Where logger&(*)(logger&) is the type of a function accepting and returning a logger by reference. To write your own manipulators, just write a function that matches that signature, and have it perform some operation on the stream:
logger& newline(logger& L) {
return L << '\n';
}
I believe that the problem is your stream doesn't overload operator<< to accept a function that has the same type as std::endl as illustrated in this answer: std::endl is of unknown type when overloading operator<<
In C++ it is the stream buffer that encapsulates the underlying I/O mechanisim. The stream itself only encapsulates the conversions to string, and the I/O direction.
Thus you should be using one of the predefined stream classes, rather than making your own. If you have a new target you want your I/O to go to (like a system log), what you should be creating is your own stream buffer (derived from std::streambuf).