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();
};
Related
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;
}
I have a problem with creating an operator<< in a class in this particular situation. I have a class that wraps a std::ostream so I can do some preprocessing for some types or some conditions before passing to the ostream, and want to pass some things straight through. I don't want to inherit the std::ostream, unless there is a good argument that I should. (I think I tried it once and found great difficulty and no success.)
I cannot use a template function because the processing depends on type in some cases, and I think the ambiguity would remain between it and those for my specific types (like 'Stuff'). Do I have to resort to using typeid ??
class MyClass
{
private:
std::ostream & m_out;
public:
MyClass (std::ostream & out)
: m_out(out)
{}
MyClass & operator<< (const Stuff & stuff)
{
//...
// something derived from processing stuff, unknown to stuff
m_out << something;
return *this;
}
// if I explicitly create operator<< for char, int, and double,
// such as shown for char and int below, I get a compile error:
// ambiguous overload for 'operator<<' on later attempt to use them.
MyClass & operator<< (char c)
{
m_out << c; // needs to be as a char
return *this;
}
MyClass & operator<< (int i)
{
if (/* some condition */)
i *= 3;
m_out << i; // needs to be as an integer
return *this;
}
// ...and other overloads that do not create an ambiguity issue...
// MyClass & operator<< (const std::string & str)
// MyClass & operator<< (const char * str)
};
void doSomething ()
{
MyClass proc(std::cout);
Stuff s1, s2;
unsigned i = 1;
proc << s1 << "using stuff and strings is fine" << s2;
proc << i; // compile error here: ambiguous overload for 'operator<<' in 'proc << i'
}
Your problem is that the value you're trying to insert is unsigned while the overloads you've provided only work on signed types. As far as the compiler is concerned, converting unsigned to int or char are both equally good/bad and result in ambiguity.
I cannot use a template function because the processing depends on type in some cases
Just make overloadings for those types.
I think the ambiguity would remain between it and those for my specific types (like 'Stuff').
No. If operator<< is overloaded for specific type, this overloading will be called. Otherwise will be called template function.
template <class T>
MyClass& operator<< (const T& t)
{
m_out << t;
return *this;
}
I have a custom class called Stream
class Stream
public:
Stream& operator<<(int i) { stream_ << i; return *this;}
template <typename CustomClass>
Stream& operator<<(const CustomClass& c) { stream_ << c.toString() /* assume this template always have toString(); return *this; }
private:
std::stringstream stream_;
};
This is a very basic example of what I actually have. And I am trying to set std::ios_base flags like following:
Stream() << 1 << std::hex << 2;
using operator;
Stream& operator<<(std::ios_base& b) { stream_.setf(b.flags()); return *this; }
from what I understand, because std::hex returns std::ios_base so it should call this and set streams' flag. But it always call the template. Note: If i remove this template, everything works just as good as you would expect but is there a way to have both?
Please feel free to ask further if you need more clarification
IOStream manipulators are not objects of type std::ios_base, they are functions that take and return std::ios_base references. So when you want to do stream insertion regarding these objects, you have to overload for function pointers:
Stream& operator<<(std::ios_base& (*manip)(std::ios_base&))
// ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
{
manip(this->stream);
return *this;
}
I am trying to create my own std::string wrapper to extend its functionality.
But I got a problem when declaring the << operator.
Here's my code so far:
my custom string class:
class MyCustomString : private std::string
{
public:
std::string data;
MyCustomString() { data.assign(""); }
MyCustomString(char *value) { data.assign(value); }
void Assign(char *value) { data.assign(value); }
// ...other useful functions
std::string & operator << (const MyCustomString &src) { return this->data; }
};
the main program:
int main()
{
MyCustomString mystring("Hello");
std::cout << mystring; // error C2243: 'type cast' : conversion from 'MyCustomString *' to 'const std::basic_string<_Elem,_Traits,_Ax> &' exists, but is inaccessible
return 0;
}
I wanted cout to treat the class as a std::string, so that I won't need to do something like:
std::cout << mystring.data;
Any kind of help would be appreciated!
Thanks.
Just fyi: my IDE is Microsoft Visual C++ 2008 Express Edition.
If you look at how all stream operators are declared they are of the form:
ostream& operator<<(ostream& out, const someType& val );
Essentially you want your overloaded function to actually do the output operation and then return the new updated stream operator. What I would suggest doing is the following, note that this is a global function, not a member of your class:
ostream& operator<< (ostream& out, const MyCustomString& str )
{
return out << str.data;
}
Note that if your 'data' object was private, which basic OOP says it probably should, you can declare the above operator internally as a 'friend' function. This will allow it to access the private data variable.
You need a free-standing function (friend of your class, if you make your data private as you probably should!)
inline std::ostream & operator<<(std::ostream &o, const MyCustomString&& d)
{
return o << d.data;
}
Firstly, you seem to have an issue with the definition of MyCustomString. It inherits privately from std::string as well as containing an instance of std::string itself. I'd remove one or the other.
Assuming you are implementing a new string class and you want to be able to output it using std::cout, you'll need a cast operator to return the string data which std::cout expects:
operator const char *()
{
return this->data.c_str();
}
That's not how you overload the << operator. You need to pass in a reference to an ostream and return one (so you can stack multiple <<, like std::cout << lol << lol2).
ostream& operator << (ostream& os, const MyCustomString& s);
Then just do this:
ostream& operator << (ostream& os, const MyCustomString& s)
{
return os << s.data;
}