I'm trying to implement a manipulator for my stream class. I don't know much about manipulators, but I think I'm doing everything right. The relevant parts of the code are below:
class stream
{
public:
stream& operator<<(bool b) { // send bool value and return *this; }
stream& operator<<(const char str[]) { // send string and return *this }
};
inline stream& endl(stream& s)
{
return s << "\r\n";
}
class stream stream;
int main()
{
stream << endl;
}
I don't know what I'm doing wrong, but instead of calling endl the compiler is calling stream::operator<<(bool). Any idea?
Seeing stream << endl; the compiler has to pick an overload from the operator <<s you provided. endl is not convertible to const char *, but it is convertible to bool, so that's what you get.
You probably meant to add an overload
stream& operator<<(stream &(*function)(stream &)) {
return function(*this);
}
inside of class stream that handles function pointers correctly.
Since your endl is neither a bool nor a const char[] (it is a free function), it is implicitly converted to a bool(true) and the following function is called:
stream::stream& operator<<(bool b)
You could define endl to be of a special type endl_t and define the right operator for it:
#include <iostream>
#include <string>
#include <array>
//Just make the operators `explicit`. See [this excellent answer on SO](http://stackoverflow.com/a/8239402/5470596).
class stream
{
public:
stream& operator<<(bool b) { std::cout << "bool\n" ; return *this; }
stream& operator<<(const char str[]) { std::cout << "const char[]\n" ; return *this; }
};
struct endl_t {} endl;
stream& operator<<(stream& s, endl_t)
{
s << "\r\n";
return s;
}
int main()
{
stream s;
s << endl; // prints "const char[]"
}
Live on coliru
That's basically the question, is there a "right" way to implement operator<< ?
Reading this I can see that something like:
friend bool operator<<(obj const& lhs, obj const& rhs);
is preferred to something like
ostream& operator<<(obj const& rhs);
But I can't quite see why should I use one or the other.
My personal case is:
friend ostream & operator<<(ostream &os, const Paragraph& p) {
return os << p.to_str();
}
But I could probably do:
ostream & operator<<(ostream &os) {
return os << paragraph;
}
What rationale should I base this decision on?
Note:
Paragraph::to_str = (return paragraph)
where paragraph's a string.
The problem here is in your interpretation of the article you link.
Equality
This article is about somebody that is having problems correctly defining the bool relationship operators.
The operator:
Equality == and !=
Relationship < > <= >=
These operators should return a bool as they are comparing two objects of the same type. It is usually easiest to define these operators as part of the class. This is because a class is automatically a friend of itself so objects of type Paragraph can examine each other (even each others private members).
There is an argument for making these free standing functions as this lets auto conversion convert both sides if they are not the same type, while member functions only allow the rhs to be auto converted. I find this a paper man argument as you don't really want auto conversion happening in the first place (usually). But if this is something you want (I don't recommend it) then making the comparators free standing can be advantageous.
Streaming
The stream operators:
operator << output
operator >> input
When you use these as stream operators (rather than binary shift) the first parameter is a stream. Since you do not have access to the stream object (its not yours to modify) these can not be member operators they have to be external to the class. Thus they must either be friends of the class or have access to a public method that will do the streaming for you.
It is also traditional for these objects to return a reference to a stream object so you can chain stream operations together.
#include <iostream>
class Paragraph
{
public:
explicit Paragraph(std::string const& init)
:m_para(init)
{}
std::string const& to_str() const
{
return m_para;
}
bool operator==(Paragraph const& rhs) const
{
return m_para == rhs.m_para;
}
bool operator!=(Paragraph const& rhs) const
{
// Define != operator in terms of the == operator
return !(this->operator==(rhs));
}
bool operator<(Paragraph const& rhs) const
{
return m_para < rhs.m_para;
}
private:
friend std::ostream & operator<<(std::ostream &os, const Paragraph& p);
std::string m_para;
};
std::ostream & operator<<(std::ostream &os, const Paragraph& p)
{
return os << p.to_str();
}
int main()
{
Paragraph p("Plop");
Paragraph q(p);
std::cout << p << std::endl << (p == q) << std::endl;
}
You can not do it as a member function, because the implicit this parameter is the left hand side of the <<-operator. (Hence, you would need to add it as a member function to the ostream-class. Not good :)
Could you do it as a free function without friending it? That's what I prefer, because it makes it clear that this is an integration with ostream, and not a core functionality of your class.
If possible, as non-member and non-friend functions.
As described by Herb Sutter and Scott Meyers, prefer non-friend non-member functions to member functions, to help increase encapsulation.
In some cases, like C++ streams, you won't have the choice and must use non-member functions.
But still, it does not mean you have to make these functions friends of your classes: These functions can still acess your class through your class accessors. If you succeed in writting those functions this way, then you won.
About operator << and >> prototypes
I believe the examples you gave in your question are wrong. For example;
ostream & operator<<(ostream &os) {
return os << paragraph;
}
I can't even start to think how this method could work in a stream.
Here are the two ways to implement the << and >> operators.
Let's say you want to use a stream-like object of type T.
And that you want to extract/insert from/into T the relevant data of your object of type Paragraph.
Generic operator << and >> function prototypes
The first being as functions:
// T << Paragraph
T & operator << (T & p_oOutputStream, const Paragraph & p_oParagraph)
{
// do the insertion of p_oParagraph
return p_oOutputStream ;
}
// T >> Paragraph
T & operator >> (T & p_oInputStream, const Paragraph & p_oParagraph)
{
// do the extraction of p_oParagraph
return p_oInputStream ;
}
Generic operator << and >> method prototypes
The second being as methods:
// T << Paragraph
T & T::operator << (const Paragraph & p_oParagraph)
{
// do the insertion of p_oParagraph
return *this ;
}
// T >> Paragraph
T & T::operator >> (const Paragraph & p_oParagraph)
{
// do the extraction of p_oParagraph
return *this ;
}
Note that to use this notation, you must extend T's class declaration. For STL objects, this is not possible (you are not supposed to modify them...).
And what if T is a C++ stream?
Here are the prototypes of the same << and >> operators for C++ streams.
For generic basic_istream and basic_ostream
Note that is case of streams, as you can't modify the C++ stream, you must implement the functions. Which means something like:
// OUTPUT << Paragraph
template <typename charT, typename traits>
std::basic_ostream<charT,traits> & operator << (std::basic_ostream<charT,traits> & p_oOutputStream, const Paragraph & p_oParagraph)
{
// do the insertion of p_oParagraph
return p_oOutputStream ;
}
// INPUT >> Paragraph
template <typename charT, typename traits>
std::basic_istream<charT,traits> & operator >> (std::basic_istream<charT,traits> & p_oInputStream, const CMyObject & p_oParagraph)
{
// do the extract of p_oParagraph
return p_oInputStream ;
}
For char istream and ostream
The following code will work only for char-based streams.
// OUTPUT << A
std::ostream & operator << (std::ostream & p_oOutputStream, const Paragraph & p_oParagraph)
{
// do the insertion of p_oParagraph
return p_oOutputStream ;
}
// INPUT >> A
std::istream & operator >> (std::istream & p_oInputStream, const Paragraph & p_oParagraph)
{
// do the extract of p_oParagraph
return p_oInputStream ;
}
Rhys Ulerich commented about the fact the char-based code is but a "specialization" of the generic code above it. Of course, Rhys is right: I don't recommend the use of the char-based example. It is only given here because it's simpler to read. As it is only viable if you only work with char-based streams, you should avoid it on platforms where wchar_t code is common (i.e. on Windows).
Hope this will help.
It should be implemented as a free, non-friend functions, especially if, like most things these days, the output is mainly used for diagnostics and logging. Add const accessors for all the things that need to go into the output, and then have the outputter just call those and do formatting.
I've actually taken to collecting all of these ostream output free functions in an "ostreamhelpers" header and implementation file, it keeps that secondary functionality far away from the real purpose of the classes.
The signature:
bool operator<<(const obj&, const obj&);
Seems rather suspect, this does not fit the stream convention nor the bitwise convention so it looks like a case of operator overloading abuse, operator < should return bool but operator << should probably return something else.
If you meant so say:
ostream& operator<<(ostream&, const obj&);
Then since you can't add functions to ostream by necessity the function must be a free function, whether it a friend or not depends on what it has to access (if it doesn't need to access private or protected members there's no need to make it friend).
Just for completion sake, I would like to add that you indeed can create an operator ostream& operator << (ostream& os) inside a class and it can work. From what I know it's not a good idea to use it, because it's very convoluted and unintuitive.
Let's assume we have this code:
#include <iostream>
#include <string>
using namespace std;
struct Widget
{
string name;
Widget(string _name) : name(_name) {}
ostream& operator << (ostream& os)
{
return os << name;
}
};
int main()
{
Widget w1("w1");
Widget w2("w2");
// These two won't work
{
// Error: operand types are std::ostream << std::ostream
// cout << w1.operator<<(cout) << '\n';
// Error: operand types are std::ostream << Widget
// cout << w1 << '\n';
}
// However these two work
{
w1 << cout << '\n';
// Call to w1.operator<<(cout) returns a reference to ostream&
w2 << w1.operator<<(cout) << '\n';
}
return 0;
}
So to sum it up - you can do it, but you most probably shouldn't :)
friend operator = equal rights as class
friend std::ostream& operator<<(std::ostream& os, const Object& object) {
os << object._atribute1 << " " << object._atribute2 << " " << atribute._atribute3 << std::endl;
return os;
}
operator<< implemented as a friend function:
#include <iostream>
#include <string>
using namespace std;
class Samp
{
public:
int ID;
string strName;
friend std::ostream& operator<<(std::ostream &os, const Samp& obj);
};
std::ostream& operator<<(std::ostream &os, const Samp& obj)
{
os << obj.ID<< “ ” << obj.strName;
return os;
}
int main()
{
Samp obj, obj1;
obj.ID = 100;
obj.strName = "Hello";
obj1=obj;
cout << obj <<endl<< obj1;
}
OUTPUT:
100 Hello
100 Hello
This can be a friend function only because the object is on the right hand side of operator<< and argument cout is on the left hand side. So this can't be a member function to the class, it can only be a friend function.
Given a class
class ostreamWrapper
{
private:
ostream * str;
public:
ostreamWrapper operator << (const char *);
}
where ostream * str will point to std::cout and ostreamWrapper operator << (const char *) sends the given text to the wrapped ostream str.
In this case, I can only instance << "const char * text" and no other printable data. Unlike directly <<ing a std::cout or std::cerr.
How can the operator method be implemented so it accepts any type of data just as std::cout or std::cerr directly do?
First, write a public operator<< template so it can accept any type and simply forward it to the wrapped ostream.
template <class T>
ostreamWrapper& operator<<(T&& x) {
*str << std::forward<T>(x);
return *this;
}
Second, in order to accept insertion of stream manipulator templates such as std::endl, add a second public operator<< that specifically accepts manipulators intended for the wrapped ostream:
ostreamWrapper& operator<<(ostream& (*manip)(ostream&)) {
*str << manip;
return *this;
}
Omitting the second overload will cause insertion of overloaded manipulators or manipulator templates to fail with "ambiguous overload" or similar error messages.
See an example of the proposed implementation, it would deduce the template parameter type and print accordingly, if you could use C++11 see #Brian answer:
#include <iostream>
using namespace std;
class ostreamWrapper {
private:
ostream* str;
public:
ostreamWrapper(ostream* str_v) : str(str_v) {}
template <typename T>
ostreamWrapper& operator<<(const T& t) {
if (str)
*str << t;
return *this;
}
};
int main() {
ostreamWrapper osw(&std::cout);
osw << 1 << " texto " << std::string(" otro texto ") << 1.2345;
return 0;
}
In my project I use a class class called Message which inherits from std::ostringstream to print out human readable information of other class types.
So its << operator is overloaded several times taking my own class types which I want to print out.
class Message : public ostringstream
{
public:
Message() {};
virtual ~Message() {};
Message& operator <<(const MyTypeA &a) { return *this << a.getStr(); };
Message& operator <<(const MyTypeB &b) { return *this << b.identifier(); };
Message& operator <<(const MyTypeC &c) { return *this << c.foo(); };
// Pass everything unknown down to ostringstream, and always return a Message&
template<class T>
Message& operator <<(const T &t)
{
(std::ostringstream&)(*this) << t;
return *this;
}
};
Without the template
MyTypeA a,b;
Message m;
m << a << "-" << b;
the code would not compile, as (m << a << "-") would return a ostringstream& which would not be able to take 'b'. So I use the template to make sure to always return a Message&.
My Problem:
Message m;
m << "Hello, world" << std::endl;
generates a veeery long compiler error and I do not know why.
Here is a minimalistic "not" compilable example of my problem, and here is the corresponding compiler output.
Do not derive from any of the stream classes to create a new stream! The only reason to derive from std::ostream or std::istream is to create a stream properly set up to use a suitable stream buffer. Instead of deriving from a stream, you should derive from std::streambuf to create a new source or destination. To create output operators for new types you'd overload operator<<() with std::ostream& as first argument and your custom type as second argument. Likewise with std::istream&.
BTW, the problem you encountered is because std::endl is a function template. Trying to pass a function template somewhere requires that the appropriate instantiation can be deduced. Since your output operators don't cover a suitable signature, the instantiation of std::endl can't be deduced. I could state what's needed but that would be pointless as it is the wrong way to go anyway.
Here is how to make your code compile: http://pastebin.com/xAt5junf
The relevant excerpt:
class Message : public ostringstream
{
public:
Message() {};
virtual ~Message() {};
};
ostream& operator <<(ostream &os, const MyTypeA &a) {
return os << a.getStr();
};
ostream& operator <<(ostream &os, const MyTypeB &b) {
return os << b.getStr();
};
Since many students I work with on common code have some problems comprehending proper stream operator overloading, I tried to create a helper template (don't know if this is a real mixin) to facilitate the code and insure correct operator implementation. Here it comes:
template<typename T> struct IoEnabled {
friend std::ostream& operator<<(std::ostream& out, T const& val) {
return val.print(out);
}
friend std::istream& operator>>(std::istream& in, T& val) {
return val.scan(in);
}
friend QTextStream& operator<<(QTextStream& out, T const& val) {
return val.print(out);
}
friend QTextStream& operator>>(QTextStream& in, T& val) {
return val.scan(in);
}
friend QDebug operator<<(QDebug dbg,T const& val){
std::stringstream myStream;
myStream << val;
dbg.nospace() << myStream.str().c_str();
return dbg;
}
};
Inheriting class:
class Foo: private IoEnabled<Foo> {
protected:
int mData;
public:
template<typename U>
U& scan(U& in) {
in >> mData;
return in;
}
template<typename U>
U& print(U& out) const {
out << mData;
return out;
}
}
The downsides of this implementation as far as I see them at the moment:
Does not work for 3rd party types
Includes inheritance and thus tight coupling with the IoClass although not every user might need
Io for a certain type
The ups:
It works ;-)
Similar stream classes can be added without modifying all classes and withou writing specific new code for every class
Since I'm not very experienced in the usage of mixins and tend to violate coding guidelines once in a while, I'd like to know if this is an appropriate usage of a mixin or how one could obtain a similar effect with another more suitable technique.
Many Thanks, Martin
If they can write scan and print template functions, they might as well write templated operators directly, skipping this entire silly mixin business.
struct Foo {
int mData;
Foo() : mData(mData) {}
};
template <typename OutputStream>
OutputStream& operator<<(OutputStream& stream, const Foo& data) {
stream << data.mData;
return stream;
}
template <typename InputStream>
InputStream& operator>>(InputStream& stream, Foo& data) {
stream >> data.mData;
return stream;
}
Also, that special-cased QDebug overload looks entirely unnecessary and wrong.