How do I overload the << operator? From the error I am getting, it seems that std::cout doesn't know how to use <<.
This is in a class:
// uint64_t UPPER, LOWER;
std::ostream & operator<<(std::ostream & stream){
if (UPPER)
stream << UPPER;
stream << LOWER;
return stream;
}
I am getting error: no match for 'operator<<' in 'std::cout << test' which doesn't seem to make sense.
edit:
Neither this:
std::ostream & operator<<(std::ostream & stream, uint128_t const & val){
if (val.upper())
stream << val.upper();
stream << val.lower();
return stream;
}
nor this:
std::ostream & operator<<(std::ostream & stream, uint128_t val){
if (val.upper())
stream << val.upper();
stream << val.lower();
return stream;
}
is changing the error.
The << operator takes two arguments, a left hand side, and a right hand side. Therefore you have to define the function with two parameters:
std::ostream operator<<(std::ostream &os, const MyClass &obj);
And you have to define it outside of your class definition, as far as I can remember. Inside of the class definition you can only have operators that take that class as the left hand side.
You typically want the operator<<() overload to be a 'free function' (outside of your class) so it can bind to the stream naturally:
// this is outside your class definition
std::ostream& operator<<(std::ostream& os, const myclass& rhs)
{
// whatever...
return os;
}
Then inside your class you declare it a friend if necessary so it can get to the class internals:
friend std::ostream& operator<<(std::ostream& os, const myclass& rhs);
An alternative to having this be a friend (which some people consider to be breaking encapsulation) is to have a public function in your class that will output itself to a stream and call that in your operator<<() overload:
// inside class myclass - a normal public member function
std::ostream& dump( std::ostream& os)
{
os << some_class_member;
// ...
return os;
}
// now, the `operator<<()` overload doesn't need to be a friend
// this is still outside your class definition
std::ostream& operator<<(std::ostream& os, const myclass& rhs)
{
return rhs.dump(os);
}
operator<< outside a class requires two arguments:
std::ostream& operator<<(std::ostream& stream, type_you_want_output const& thing)
Related
I tried to write an simple example for the <<-operator-overloading.
Before, i've never used the keyword "friend". But it does not work without it. What is the mistake i did or why do i need the friend keyword here?
class rational{
public:
rational(double num, double count)
: n(num),c(count){}
rational& operator+=(const rational& b){
this->n+= b.n;
this->c+= b.c;
return *this;
}
friend std::ostream& operator<<(std::ostream& os, const rational& obj)
{
std::cout << obj.n << "," << obj.c << std::endl;
return os;
}
private:
double n;
double c;
};
Thanks
You didn't make any mistake. The friend keyword gives your operator<<() implementation access to private (and protected, if you had any) members of your class.
Note that because it's a friend, operator<<() here is implicitly a free function and not a member function (if it were a member function, it could access private things already!). Because it's declared and defined only inside the class, it can only be found by argument-dependent lookup, but this is fine for operator<< and is a detail you don't have to worry about yet.
You want to stream objects whose internals are not accessible through their class' public interface, so the operator can't get at them. Then you have two choices: Either put a public member into the class which does the streaming
class T {
public:
void stream_to(std::ostream& os) const {os << obj.data_;}
private:
int data_;
};
and call that from the operator:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
obj.stream_to(os);
return os;
}
or make the operator a friend
class T {
public:
friend std::ostream& operator<<(std::ostream&, const T&);
private:
int data_;
};
so that it can access the class' private parts:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
os << obj.data_;
return os;
}
You are declaring and defining the operator inside the class, thus without friend it has an implicit first operand of type rational. You wouldn't have such problem if you had declared the operator outside the class, but then you wouldn't have access to n and c.
I am new to C++ programming and am having trouble implementing this operator overloading. It gives the error that no operator "<<" matches these operands.
class class1{
public:
bool operator==(class1 &);
friend ostream & operator<<(ostream &, class1 &);
private:
string name;
};
/*Friend ostream & operator <<*/
ostream & operator << (ostream & os, class1 & obj){
os << obj.name;
return os;
}
Someone mentioned I need another overloaded operator, but I can't figure out how to make it work with another overloaded operator
Here is the situation with your code; you have a private member string variable within your class where no outside object can set this variable. Your class does not contain a defined constructor nor a setting method. When I tried your code I had to change your operator declaration and definition from this:
std::ostream& operator<<( std::ostream& os, class1& obj );
to this:
std::ostream& operator<<( std::ostream& os, const class1& obj );
in order for it to compile. However when it came to building the project I was getting a Linker Error of an unresolved identifier. What was happening here is that the ostream object that you are declaring as a friend to your class object does know about the private member string but it can not do anything with it since this string is empty or not valid. I changed your class to this:
#include <conio.h>
#include <string>
#include <iostream>
class class1 {
friend std::ostream& operator<<( std::ostream& out, const class1& other );
private:
std::string m_strName;
public:
explicit class1( std::string& strName ) : m_strName( strName ) {}
void setName( std::string& strName ) { m_strName = strName; }
std::string getName() const { return m_strName; }
};
std::ostream& operator << ( std::ostream& out, class1& obj ) {
out << obj.m_strName << std::endl;
// out << obj.getName() << std::endl;
return out;
}
int main() {
class1 a( std::string( "class1" ) );
std::cout << a << std::endl;
std::cout << "Press any key to quit" << std::endl;
_getch();
return 0;
}
This compiles, builds, links and executes properly and displays appropriate text and exits with a value of 0 for no errors. I am using MSV2013 on a Win7 machine. The main issue was that since your class had no way to populate its string member upon construction the ostream operator object could not resolve the variable in use.
The overload operator<<(std::ostream&, std::string) is actually defined by #include <string>.
Although std::string is also defined by that header, it is still possible for std::string to be defined but not this operator overload, if you did not include that header.
The C++ standard requires that certain headers provide certain features, but it does not prohibit that feature also being provided by another header. In your case, the compiler/library writer has decided that implementing some other feature in another header was most easily done by defining std::string, but it would have done this by having a separate file defining std::string which is included both by <string> and by the other header.
remove the keyword "friend" for ostream if you intent for it to be a public member. If your want ostream to be friend move it above public:
operator== should have two const parameter, const if you do not intend to change.
friend ostream & operator<<(ostream &, const class1 &);
public:
bool operator==(const class1& x, const class1& y);
or
public:
bool operator==(const class1& x, const class1& y);
ostream & operator<<(ostream &, const class1 &);
make operator << second parameter a const might help
ostream & operator << (ostream & os, const class1 & obj){
os << obj.name;
return os;
}
Code snippet from lexical_cast:
class lexical_castable {
public:
lexical_castable() {};
lexical_castable(const std::string s) : s_(s) {};
friend std::ostream operator<<
(std::ostream& o, const lexical_castable& le);
friend std::istream operator>>
(std::istream& i, lexical_castable& le);
private:
virtual void print_(std::ostream& o) const {
o << s_ <<"\n";
}
virtual void read_(std::istream& i) const {
i >> s_;
}
std::string s_;
};
std::ostream operator<<(std::ostream& o,
const lexical_castable& le) {
le.print_(o);
return o;
}
std::istream operator>>(std::istream& i, lexical_castable& le) {
le.read_(i);
return i;
}
Based on document,
template<typename Target, typename Source>
Target lexical_cast(const Source& arg);
1> Returns the result of streaming arg into a standard library
string-based stream and then out as a Target object.
2> Source is OutputStreamable
3> Target is InputStreamable
Question1> For User Defined Type (UDT), should the OutputStreamable or InputStreamable always have to deal with std::string? For example, given a class containing a simple integer as member variable, when we define the operator<< and operator>>, what is the implementation code looks like? Do I have to convert the integer as a string? Based on my understanding, it seems that UDT always has to deal with std::string in order to work with boost::lexical_cast and boost::lexcial_cast needs the intermediate std::string to do the real conversion jobs.
Question2> Why the return value of operator<< or operator>> in above code is not reference to std::ostream& or std::istream& respectively?
To make your class usable with lexical_cast, just define the "stream" operators for it.
From Boost.LexicalCast Synopsis:
Source is OutputStreamable, meaning that an operator<< is defined that takes a std::ostream or std::wostream object on the left hand side and an instance of the argument type on the right.
Target is InputStreamable, meaning that an operator>> is defined that takes a std::istream or std::wistream object on the left hand side and an instance of the result type on the right.
Target is CopyConstructible [20.1.3].
Target is DefaultConstructible, meaning that it is possible to default-initialize an object of that type [8.5, 20.1.4].
:
// either inline friend, out-of-class friend, or just normal free function
// depending on whether it needs to access internel members
// or can cope with the public interface
// (use only one version)
class MyClass{
int _i;
public:
// inline version
friend std::ostream& operator<<(std::ostream& os, MyClass const& ms){
return os << ms._i;
}
// or out-of-class friend (friend declaration inside class only)
friend std::ostream& operator<<(std::ostream& os, MyClass const& ms);
// for the free function version
int get_i() const{ return _i; }
};
// out-of-class continued
std::ostream& operator<<(std::ostream& os, MyClass const& ms){
return os << ms._i;
}
// free function, non-friend
std::ostream& operator<<(std::ostream& os, MyClass const& ms){
return os << ms.get_i();
}
The same of course for operator>>.
I want to overload the operator << in one of my classes.
The signature goes like this:
friend std::ostream& operator<<(std::ostream& os, const Annuaire& obj)
When I try to define it in the .cpp file it says that the operator<< exactly takes 1 argument, however, when I define it in the .h, it compiled/works fine.
This is how I define it in the .cpp file :
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ... }
Does it have anything to do with friend functions needing to be defined in header files?
It can be defined in a cpp file, but it needs to at least be declared in a header file, otherwise all places where you want to use it will only see the stuff the stream itself gives you, not your overload.
// .h and in class
friend std::ostream& operator<<(std::ostream& os, MyClass const& v);
// .cpp
std::ostream& operator<<(std::ostream& os, MyClass const& v){
// print it
}
The problem is with the way you're defining it. It's not a member of the class, it's just a friend of the class. You need to drop the Annuaire:: prefix. So, change this:
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ...
to this:
std::ostream& operator<<(std::ostream& os, const Annuaire& obj){ // ...
The reason for the error message is that Annuaire::operator<<(std::ostream& os, const Annuaire& obj) would expect three arguments: the Annuaire instance that it's called on (as this), and and two additional arguments (os and obj).
As mentioned in David's answer, in this case the operator is not a member function, it is merely a friend function in the same namespace. This pointed me in the right direction in solving a very similar issue.
I'm posting this answer because it wasn't immediately obvious to me. Maybe because the implementation file where I was adding the operator wasn't fully enclosed in the namespace, and used a using-directive instead.
Shouldn't be relevant but I'm using VS2013.
//Foo.h
namespace Bar{
class Foo
{
public:
Foo();
private:
int n;
friend std::ostream & operator<<(std::ostream &, Foo const &);
};
}
//Foo.cpp
using namespace Bar; //won't apply to the operator definition
Foo::Foo(){}// doesn't require the Bar qualifier because of the using-directive
//the operator required the Bar namespace qualifier
std::ostream & Bar::operator<<(std::ostream & o, Foo const & x)
{
return o << x.n;
}
Friend functions, even if they seem to be declared inside the class are not member functions but rather namespace level functions (in the enclosing namespace). In your code you declare the friend function correctly, but you try to define it as a member function of the class:
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){
That definition would be for a member function of Annuaire, called operator<<, that takes two arguments, which is invalid as operator<< can be overloaded in one of two ways: as a free function taking two arguments (left hand side and right hand side) or as a member function of the class that appears in the lhs of the expression taking an argument of the rhs type. In this particular case, since the lhs is std::ostream and you cannot modify it, you are left with the only option of using a free function:
std::ostream& operator<<(std::ostream& os, const Annuaire& obj)
No such restriction; you're probably just writing it wrong. Should be something like this:
class Foo
{
int n;
friend std::ostream & operator<<(std::ostream &, Foo const &);
};
std::ostream & operator<<(std::ostream & o, Foo const & x)
{
return o << x.n;
}
I have class Person (first name, last name, address, age) and overloaded operators << and >> to use it with filestreams:
ostream& operator<< (ostream& outStream, Person& person)
{
...
}
istream& operator>> (istream& inStream, Person& person)
{
...
}
It works fine - I can read from and write to file easily, but I have added two classes inherited from Person: Student and Worker.
I wrote overloaded operators for them, very similar to those above:
ostream& operator<< (ostream& outStream, Worker& worker)
{
...
}
istream& operator>> (istream& inStream, Worker& worker)
{
...
}
ostream& operator<< (ostream& outStream, Student& student)
{
...
}
istream& operator>> (istream& inStream, Student& student)
{
...
}
Only difference are two more fields in each class. The problem is, that when I use overloaded operators with either Student or Worker it seems my compiler uses operators for person. Probably it makes hidden conversion from Student or Worker to Person, but as a result there are no those additional fields written to the file.
offstream << People works just the same as offstream << Students or offstrem Workers.
Maybe placing overloaded operators declarations for inherited classes first, and for Person later in the code would solve the issue, but i don't find it an elegant solution.
If you have some ideas how to manage with the problem above, I would appreciate.
Two things. First, make your operators take references to const, like this:
ostream& operator<< (ostream& outStream, const Person& person)
To solve your problem, a common pattern is to provide your types with a protected virtual toString method, and have the operator just call that. You can then just overload this method in the sub-classes, and even reuse the super-class implementation if you just want to append some values to the string.
Example:
class Person {
// other stuff
protected:
virtual std::string toString();
friend ostream& operator<< (ostream& outStream, const Person& person)
};
ostream& operator<< (ostream& outStream, Person& person)
{
ostream << person.toString();
return outStream;
}
Edit
Actually, I like larsmans suggestion even better:
class Person {
// other stuff
protected:
virtual void print(ostream & stream) const;
friend ostream& operator<< (ostream& outStream, const Person& person)
};
ostream& operator<< (ostream& outStream, Person& person)
{
person.print(outStream);
return outStream;
}
This will be easier to implement than the toString idea, because you need no temporary stringstream or anything like that to build the string.
Most probably the code which calls the << operator accesses the object through a pointer or reference to Person, thus calling the operator for the Person type. The usual way of handling this is to provide a virtual method on the parent (i.e. Person) class which does the writing (getting the stream as an argument), and have the operator<< call this method to do the work. You need to provide the operator<< only for the parent class, the virtual dispatch mechanism will take care of choosing the right method for the object provided.
class Person {
// ...
protected:
virtual ostream& stream_write(ostream&) const; //override this in child classes
virtual istream& stream_read(istream&); //this too
public:
friend ostream& operator<< (ostream& stream, const Person& obj)
{ return obj.stream_write(stream); }
friend istream& operator>> (istream& stream, Person& obj)
{ return obj.stream_read(stream); }
};
Your operators could call a virtual method. Something like this :
struct A
{
virtual ~A(){}
virtual std::ostream& Print( std::ostream &os ) const
{
// print what you want
return os;
}
};
struct B : A
{
virtual ~B(){}
virtual std::ostream& Print( std::ostream &os ) const
{
// print what you want
return os;
}
};
Then create the operator<< only for the base class :
std::ostream& operator<<( std::ostream &os, const A &a)
{
return a.Print(os);
}
I usually call a virtual function streamIn and streamOut in the overloaded streaming operators, in that way I can actually create a template streaming function that works for all classes with streamIn and streamOut functions.