Error ocurred with the following try to operator overloading:
#include<iostream>
#include<string>
#include<ostream>
using namespace std;
class Dollar
{
private:
float currency, mktrate, offrate;
public:
Dollar(float);
float getDollar() const;
float getMarketSoums() const;
float getofficialSoums() const;
void getRates();
// In the following function I was trying to overload "<<" in order to print all the data members:
friend void operator<<(Dollar &dol, ostream &out)
{
out << dol.getDollar() << endl;
out << dol.getMarketSoums() << endl;
out << dol.getofficialSoums() << endl;
}
};
Dollar::Dollar(float d)
{
currency = d;
}
float Dollar::getDollar() const
{
return currency;
}
float Dollar::getMarketSoums() const
{
return mktrate;
}
float Dollar::getofficialSoums() const
{
return offrate;
}
void Dollar::getRates()
{
cin >> mktrate;
cin >> offrate;
}
int main()
{
Dollar dollar(100);
dollar.getRates();
// In this line I am getting the error. Could you please help to modify it correctly?
cout << dollar;
system("pause");
return 0;
}
You have to pass std::ostream object as the first parameter to the insertion operator << not as the second one as long as you are calling it that way:
friend void operator << (ostream &out, Dollar &dol);
You should make the object passed in to the insertion operator constant reference as long as this function is only prints and not intending to modify the object's members:
friend void operator << (ostream &out, const Dollar& dol);
So pass by reference to avoid multiple copies and const to avoid unintentional modification.
If you want to invoke to get it work the way you wanted you can do this:
friend void operator<<(const Dollar &dol, ostream &out){
out << dol.getDollar() << endl;
out << dol.getMarketSoums() << endl;
out << dol.getofficialSoums() << endl;
}
And in main for example:
operator << (dollar, cout); // this is ok
dollar << cout; // or this. also ok.
As you can see I reversed the order of calling the insertion operator to match the signature above. But I don't recommend this, it is just to understand more how it should work.
Related
This question stems from a larger code I am working on but hopefully I can break it down to simplify:
Say I have two classes, one which holds 2 integer variables, and another which contains a vector that holds the first class
class TwoInts {
int num1;
int num2;
}
class NumHold {
std::vector<TwoInts> numVector;
}
How would I go about printing my numHold class exactly? I know I would have to provide an overloaded stream operator
std::ostream &operator<< (std::ostream &out, const NumHold &myNumHold){;}
But I'm a little confused as to the syntax regarding how I would print out these integers from the vector. I also understand that in order for the stream operator to work I would have to add it to my class as a friend, I just wanted to keep my NumHold class as simplified as possible for the examples sake. Hopefully this was clear enough of an explanation, any help is appreciated
Treat out how you would treat std::cout, then return it at the end of the function:
std::ostream& operator<<(std::ostream& out, const NumHold &myNumHold){
//one possible output format
for(const auto& twoInt : myNumHold.numVector){
out << twoInt.num1 << ", " << twoInt.num2 << '\n'; //pretend out is std::cout
}
return out; //don't forget to return it at the end
}
If appropriate, declare the overload as a friend function within the NumHold class:
#include<iostream>
class NumHold {
private:
std::vector<TwoInts> numVector;
public:
//friend operator overload declaration
friend std::ostream& operator<<(std::ostream& out, const NumHold& myNumHold);
};
In your example, it is appropriate, as the overload function accesses private variables.
You need to be able to access the members of each TwoInts in order to print them. One way to do this is to make them public.
class TwoInts {
public: //lets NumHold access variables to print
int num1;
int num2;
};
class NumHold {
public:
std::vector<TwoInts> numVector;
friend std::ostream& operator << (std::ostream& out, const NumHold& myNumHold) {
for (const TwoInts& ti : myNumHold.numVector) {
out << "(" << ti.num1 << ", " << ti.num2 << ")" << std::endl;
}
return out;
}
};
You can also consider adding printing methods to your classes:
#include<iostream>
class TwoInts {
private:
int num1;
int num2;
public:
void printnum1(){
std::cout << num1;
}
void printnum2(){
std::cout << num2;
}
}
class NumHold {
private:
std::vector<TwoInts> numVector;
public:
//this function prints the private attributes of the class
void printnumVector(){
for (int i = 0; i < numVector.size(); i++){
std::cout << numVector[i].printnum1() << " " << numVector[i].printnum2() << std::endl;
}
}
};
I'm having troubles understanding the reason why the compiler accuses error, when the return type of a << operator overload is std::string. Could you please help me understand?
Bellow is an reproducible example, which gives a gigantic error.
class XY
{
int X__;
int Y__;
public:
XY(int x, int y):X__(x), Y__(y){}
~XY(){}
std::string operator<<(const XY_cartesiano& c)
{
std::stringstream ss;
ss << "{ " << X__ << ", " << Y__ << " }";
return ss.str();
}
int x() const{return X__;}
int y() const{return Y__;}
};
void main()
{
XY a(1,2);
std::cout << a;
}
Let's take something like this as an example:
cout << "My number is " << 137 << " and I like it a lot." << endl;
This gets parsed as
((((cout << "My number is ") << 137) << " and I like it a lot.") << endl);
In particular, notice that the expression cout << "My number is " has to evaluate to something so that when we then try inserting 137 with << 137 the meaning is "take 137 and send it to cout."
Imagine if cout << "My number is " were to return a string. In that case, the << 137 bit would try to use the << operator between a string on the left-hand side and an int on the right-hand side, which isn't well-defined in C++.
The convention is to have the stream insertion operator operator << return a reference to whatever the left-hand side stream is so that these operations chain well. That way, the thing on the left-hand side of << 137 ends up being cout itself, so the above code ends up essentially being a series of chained calls to insert things into cout. The signature of these functions therefore usually look like this:
ostream& operator<< (ostream& out, const ObjectType& myObject) {
// ... do something to insert myObject into out ... //
return out;
}
Now, everything chains properly. Notice that this function is a free function, not a member function, and that the left-hand side is of type ostream and the right-hand side has the type of your class in it. This is the conventional way to do this, since if you try overloading operator << as a member function, the left-hand side will be an operand of your class type, which is backwards from how stream insertion is supposed to work. If you need to specifically access private fields of your class in the course of implementing this function, make it a friend:
class XY {
public:
...
friend ostream& operator<< (ostream& out, const XY& myXY);
};
ostream& operator<< (ostream& out, const XY &myXY) {
...
return out;
}
Correct way to overload << operator in your case is
ostream& operator<<(ostream& os, const XY& c)
{
os << c.X__ <<" "<< c.Y__ ;
return os;
}
You have overloaded operator<< in a way that's incompatible with the conventions you must follow when you intend to use the operator with a std::ostream object like std::cout.
In fact, your operator<<'s signature has nothing to do with streams at all! It is just a member function of XY which takes another XY (which it then does not use), returns a string and has an unsual name. Here's how you would theoretically call it:
XY a(1,2);
XY b(1,2);
std::string x = (a << b);
The correct way to overload operator<< for use with streams is to make the operator a non-member function, add a stream reference parameter and return a stream reference to the stream argument. You also do not need a string stream; you write directly to the stream you get:
#include <iostream>
class XY
{
int x;
int y;
public:
XY(int x, int y) : x(x), y(y) {}
int X() const { return x; }
int Y() const { return y; }
};
std::ostream& operator<<(std::ostream& os, XY const& c)
{
os << "{ " << c.X() << ", " << c.Y() << " }";
return os;
}
int main()
{
XY a(1,2);
std::cout << a;
}
I learnt how to do operator overloading of Stream Insertion Operator. But one doubt remains.
#include<iostream>
class INT
{
int i;
friend std::ostream& operator<<(std::ostream&,INT&);
public:
INT():i(100){}
};
std::ostream& operator<<(std::ostream& obj,INT & data)
{
obj<<data.i;
return obj;
}
int main()
{
INT obj;
std::cout<<obj;
}
What significance return obj; has?
Do that return have any use further?
Are We forced to do that return because of the syntax of the operator<< without any usefulness?
Remember how you can write code like this:
cout << "The data is: " << somedata << endl;
This is actually the same as:
((cout << "The data is: ") << somedata) << endl;
For this to work, the << operator has to return the stream.
I'm working in a Big Integer implementation in C++ and I'm trying to use cout with my BigInt class. I already overloaded the << operator but it doesn't work in some cases.
Here is my code:
inline std::ostream& operator << (ostream &stream, BigInt &B){
if (!B.getSign()){
stream << '-';
}
stream << B.getNumber();
return stream;
}
The code above works with:
c = a + b;
cout << c << endl;
But fails with:
cout << a + b << endl;
In the first case the program runs fine, but in the second the compiler gave an error:
main.cc: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
It's possible to overload the << operator for function in both cases?
Methods:
string getNumber ();
bool getSign ();
string BigInt::getNumber (){
return this->number;
}
bool BigInt::getSign (){
return this->sign;
}
As chris already pointed out in comments very quickly (as usual), you have a temporary created in here:
cout << a + b << endl;
You cannot bind that to a non-const reference. You will need to change the signature of your operator overloading by adding the const keyword to the reference.
This code works for me with a dummy BigInt implementation (as you have not shared yours):
#include <iostream>
using namespace std;
class BigInt
{
public:
bool getSign() const { return true; }
int getNumber() const { return 0; }
const BigInt operator+(const BigInt &other) const {}
};
inline std::ostream& operator << (ostream &stream, const BigInt &B){
// ^^^^^
if (!B.getSign()){
stream << '-';
}
stream << B.getNumber();
return stream;
}
int main()
{
BigInt a, b, c;
c = a + b;
cout << c << endl;
cout << a + b << endl;
return 0;
}
But yeah, I agree that the error message is not self-explanatory in this particular case.
Change
inline std::ostream& operator << (ostream &stream, BigInt &B){
to
inline std::ostream& operator << (ostream &stream, BigInt const& B){
c can be a used where BiInt& is expected but a+b cannot be because a+b is a temporary. But it can be used where BigInt const& is expected.
I am trying to overload << operator to print Currency (user defined type)
#include <iostream>
using namespace std;
struct Currency
{
int Dollar;
int Cents;
ostream& operator<< (ostream &out)
{
out << "(" << Dollar << ", " << Cents << ")";
return out;
}
};
template<typename T>
void DisplayValue(T tValue)
{
cout << tValue << endl;
}
int main() {
Currency c;
c.Dollar = 10;
c.Cents = 54;
DisplayValue(20); // <int>
DisplayValue("This is text"); // <const char*>
DisplayValue(20.4 * 3.14); // <double>
DisplayValue(c); // Works. compiler will be happy now.
return 0;
}
But getting the following error.
prog.cpp: In instantiation of ‘void DisplayValue(T) [with T = Currency]’:
prog.cpp:34:16: required from here
prog.cpp:22:9: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
cout << tValue << endl;
^
In file included from /usr/include/c++/4.8/iostream:39:0,
from prog.cpp:1:
/usr/include/c++/4.8/ostream:602:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Currency]’
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
Can anyone help me if i am missing any thing or doing anything wrong here?
First you need to fix the operator by adding Currency const& c as the second parameter (as it come s on the right hand side).
Then you have two options:
1: Add Friend
struct Currency
{
int Dollar;
int Cents;
friend ostream& operator<< (ostream &out, Currency const& c)
{
return out << "(" << c.Dollar << ", " << c.Cents << ")";
}
};
2: Move the definition outside the class
struct Currency
{
int Dollar;
int Cents;
};
ostream& operator<< (ostream &out, Currency const& c)
{
return out << "(" << C.Dollar << ", " << c.Cents << ")";
}
Either works and is fine.
Personally I like option-1 as it documents the tight coupling of the output operator to the class that it is outputting. But this is such a simple case that either works just fine.
The reason that it can not be a member is that the first parameter is a stream (the left hand side value of the operator is the first parameter). This does not work for members as the first parameter is the hidden this parameter. So technically you could add this method to std::ostream. Unfortunately you don't have accesses (and not allowed to) modify std::ostream. As a result you must make it a free standing function.
Example showing it can be a member:
struct X
{
std::ostream operator<<(int y)
{
return std::cout << y << " -- An int\n";
}
};
int main()
{
X x;
x << 5;
}
That works fine here.
This is because the compiler translates
x << 5;
into
// not real code (pseudo thought experiment code).
operator<<(x, 5)
// Equivalent to:
X::operator<<(int y)
// or
operator<<(X& x, int y)
Because x has a member function operator<< this works fine. If x did not have a member function called operator<< then the compiler would look for a free standing function that takes two parameters with X as the first and int as the second.
You don't put it into your class, you put if afterwards. Since your members are public there is no need to declare it a friend:
struct Currency
{
int Dollar;
int Cents;
};
ostream& operator<< (ostream &out, const Currency& c)
{
out << "(" << c.Dollar << ", " << c.Cents << ")";
return out;
}
Overload it like below, and put it outside of class declaration (you don't need friendship!):
ostream& operator<< (ostream &out, const Currency &c)
{ //^^^^^^^^^^^^^^^^
out << "(" << c.Dollar << ", " << c.Cents << ")";
return out;
}
Funny thing with your code is, you have to use the operator like this:
c << cout; // !!
The way you've written your inserter method, the only way to get it to work would be to do:
c << std::cout;
But instead, if you know your inserters won't need to access any private variables, simply do as the other answers say and create a global function that takes both arguments:
std::ostream& operator <<(std::ostream& os, const Currency& c);
#include<iostream>
using namespace std;
class myclass
{
int x;
public:
myclass() //constructor
{
x=5;
}
friend ostream& operator<<(ostream &outStreamObject,myclass &object); //standard way
void operator<<(ostream &outStreamObject) //Another way.
{
outStreamObject<<this->x;
}
};
ostream& operator<<(ostream &outStreamObject,myclass &object)
{
cout<<object.x;
return outStreamObject;
}
int main()
{
//standard way of overload the extraction operator
myclass object1,object2;
cout<<object1<<" "<<object2;
cout<<endl;
//overloading the extraction operator with using friend function
object1.operator<<(cout);
return 0;
}
It is not at all necessary that the insertion and the extraction operators can be overloaded only by using the friend function.
The above code overloads the extraction operator with and without the friend function. The friend function implementation is favoured because cout can be used the way it is used for other datatypes.
Similary you can overload the insertion operator.
You need to make it friend :
Also you need to give it the right arguments. an ostream and the currency.
friend ostream& operator<< (ostream& stream, const Currency& c )
{
stream << "(" << c.Dollar << ", " << c.Cents << ")";
return stream;
}
Edit:
As you can see in the comments, you don't have to make it friend. You can put it outside the structure.
Currency c;
c.Dollar = 10;
c.Cents = 54;
DisplayValue(c); // Works. compiler will be happy now.