I'm trying to apply some concepts of operator loading that I've learnt in the following C++ class.
#include<iostream>
using namespace std;
class Point
{
private:
int x, y;
public:
Point(int, int);
Point operator+(const Point&);
friend istream& operator>>(istream& in, Point&);
friend ostream& operator<<(ostream& out, Point&);
Point operator=(const Point&);
};
Point::Point(int x = 0, int y = 0)
:x(x), y(y){}
Point Point::operator+(const Point& p)
{
int r1, r2;
r1 = x + p.x;
r2 = y + p.y;
return Point(r1, r2);
}
Point Point::operator=(const Point& p)
{
this->x = p.x;
this->y = p.y;
return *this;
}
istream& operator>>(istream& in, Point& p)
{
char openParenthesis, closeParenthesis, comma;
cout << "Enter data in the format (1,2): ";
in >> openParenthesis >> p.x >> comma >> p.y >> closeParenthesis;
return in;
}
ostream& operator<<(ostream& out, Point& p)
{
out << "(" << p.x << "," << p.y << ")";
return out;
}
int main()
{
Point a, b;
cin >> a >> b;
cout << "a + b is: " << a + b << endl;
return 0;
}
The code compiles and runs fine on Visual Studio. But when I try to compile it on Linux with gcc, it throws a long list of errors along the lines of:
In file included from /usr/include/c++/4.8/iostream:39:0,
from optr_overload.cpp:1: /usr/include/c++/4.8/ostream:471:5: note: template std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, _CharT)
operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
^ /usr/include/c++/4.8/ostream:471:5: note: template argument deduction/substitution failed: optr_overload.cpp:53:30: note:
deduced conflicting types for parameter ‘_CharT’ (‘char’ and ‘Point’)
cout << "a + b is: " << a + b << endl;
I understand that the problem lies with the line where I passed "a + b" to the overloaded binary stream insertion operator which only receives reference to one Point object as the argument. But I've no idea how to fix the code other than assigning "a + b" to a third object and pass that single object as the argument to "<<". Could someone explain to me what exactly needs to be done in order for gcc to compile my code, preferably without involving the use of an extra placeholder object.
The value computed with a + b is a temporary object and therefore cannot be passed as a Point& to operator<<; the language only allows temporaries to be passed as const Point& instead. Just change he declaration of the output operator to accept a const Point&.
Allowing passing a temporary result as a non-const reference was a known bug in old versions of VC++.
You've got almost everything right, but your ostream& operator<<() should take Point by a const reference:
friend ostream& operator<<(ostream& out, const Point&);
This should fix your issue.
(And don't worry about Point::x and Point::y being private, you've already declared your operator<< as a friend.)
Related
I create the class 'Point', overload the operator '+' between 2 Point object and the operator '<<' to show the Point object. I can't compile and run the code.
The error is that there is no operator "<<" matched. This is occured to "cout << "p3: " << (p1+p2) << endl;"
class Point {
public:
Point(int x=0, int y=0) : _x(x), _y(y) {};
Point operator +(Point &p);
int getX() {
return _x;
}
int getY() {
return _y;
}
friend ostream& operator <<(ostream& out, Point &p);
private:
int _x, _y;
};
Point Point::operator +(Point &p) {
Point np(this->_x+p.getX(), this->_y+p.getY());
return np;
}
ostream& operator <<(ostream &out, Point &p) {
out << '(' << p._x << ',' << p._y << ')';
return out;
}
int main() {
Point p1(1, 2);
Point p2;
cout << "p1: " << p1 << endl;
cout << "p2: " << p2 << endl;
cout << "p3: " << (p1+p2) << endl;
system("pause");
return 0;
}
The expression
(p1+p2)
is an rvalue. The function
ostream& operator <<(ostream &out, Point &p)
expects a reference to Point. You can't pass an rvalue to this function. Change it to
ostream& operator <<(ostream &out, const Point &p)
in the declaration and the definition.
C++ only allows a temporary to be passed to a const reference. See this: How come a non-const reference cannot bind to a temporary object?
Modify a temporary is meaningless. You need to define a const reference to promise you won't modify it and extend its lifetime.
When overloading operators, const correctness is not optional. The following prototypes are what you require...
Point operator + (const Point &p) const;
friend ostream& operator <<(ostream& out, const Point &p);
I'm a C++ beginner, trying to learn from online videos. In of the operator overloading examples in the lectures the following code is there and gives the error
error: no match for 'operator<<' in 'std::cout << operator+(((point&)(& p1)), ((point&)(& p2)))'compilation terminated due to -Wfatal-errors.
on the line marked with comment. Can someone please tell what's wrong in the code? I am just trying what the professor explained in the lecture but can't compile.
===============
#include <iostream>
using namespace std;
class point{
public:
double x,y;
};
point operator+ (point& p1, point& p2)
{
point sum = {p1.x + p2.x, p1.y + p2.y};
return sum;
}
ostream& operator<< (ostream& out, point& p)
{
out << "("<<p.x<<","<<p.y<<")";
return out;
}
int main(int argc, const char * argv[])
{
point p1 = {2,3};
point p2 = {2,3};
point p3;
cout << p1 << p2;
cout << p1+p2; // gives a compliation error
return 0;
}
It's just a problem with const correctness. Your operator+ returns a temporary, so you can't bind a non-const reference to it when calling operator<<. Make the signature:
ostream& operator<< (ostream& out, const point& p)
While you don't need to do it to fix this compilation error, you won't be able to add const points unless you fix the operator+ similarly:
point operator+(const point& p1, const point& p2)
Change the parameter type from point& to const point& for operator+ and operator<<. Non-const reference cannot bind to a temporary (which is returned by operator+) and that is causing the compile error.
The reason is the second parameter should be a const reference. (you don't want it gets modified, right?) So, it is like,
std::ostream& operator<< (std::ostream &out, const Point &p)
{
out << "(" << p.x << ", " << p.y << ")";
return out;
}
Is it possible to create an overload for the ostream operator that does an arithmetic operation (addition for example) and then streams out the result? The standard ostream overload that can be found all over the web can only stream from a single variable. I need something that does the following:
std::cout << x+y << std::endl;
or even more complex expressions like:
std::cout << x*y+(3*z)^2 << std::endl;
where x, y, and z are instances of a simple custom-made struct where arithmetic operations are already defined (overloaded).
EDIT:
Here is my code:
struct scalar //complex scalar data structure
{
friend scalar operator^(const scalar&, int); //integer power operator overload
friend scalar exp(const scalar&); //exponential power function
std::ostream& operator<<(std::ostream&, const scalar&)
protected:
double re;
double im;
public:
double real() {return re;} //returns the real part
double imag() {return im;} //returns the imaginary part
scalar(double _re, double _im) {re=_re;im=_im;} //constructor 1
scalar(double _re) {re=_re;im=0.0;} //constructor 2
scalar(const scalar& s): re(s.re), im(s.im) {} //copy constructor
scalar& operator=(const scalar& rhs) //assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
re=rhs.re; //sets real parts equal
im=rhs.im; //sets imaginary parts equal
return *this;
}
scalar& operator+=(const scalar& rhs) //compound addition-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
re=re+rhs.re; //adds real parts
im=im+rhs.im; //adds imaginary parts
return *this;
}
scalar& operator*=(const scalar& rhs) //compound multiplication-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
double x1=re; double x2=rhs.re; double y1=im; double y2=rhs.im;
re=x1*x2-y1*y2; //multiplies real parts
im=x1*y2+x2*y1; //multiplies imaginary parts
return *this;
}
scalar& operator-=(const scalar& rhs) //compound subtraction-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
re=re-rhs.re; //adds real parts
im=im-rhs.im; //adds imaginary parts
return *this;
}
scalar& operator/=(const scalar& rhs) //compound division-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
double x1=re; double x2=rhs.re; double y1=im; double y2=rhs.im;
double n;
n =pow(x2,2)+pow(y2,2);
if (n==0) throw(1);
re=(x1*x2+y1*y2)/n; //multiplies real parts
im=(x2*y1-x1*y2)/n; //multiplies imaginary parts
return *this;
}
const scalar operator+(const scalar& b) //addition operator overload
{
scalar c = *this;
c+=b;
return c;
}
const scalar operator*(const scalar& b) //addition operator overload
{
scalar c = *this;
c*=b;
return c;
}
const scalar operator-(const scalar& b) //addition operator overload
{
scalar c = *this;
c-=b;
return c;
}
const scalar operator/(const scalar& b) //addition operator overload
{
scalar c = *this;
c/=b;
return c;
}
};
scalar i(0.0,1.0);
scalar j(0.0,1.0);
std::ostream& operator<<(std::ostream& out, const scalar& s)
{
out << s.re << '+' << s.im << 'i';
return out;
}
scalar operator^(scalar a, int b) //integer power operator overload
{
double x=a.real(); double y=a.imag();
if (x==0) throw(1);
int r=sqrt(pow(x,2)+pow(y,2));
int arg=atan2(y,x);
scalar c(r*cos(arg),r*sin(arg));
return c;
}
scalar exp(const scalar& s) //exponential power function
{
double x=s.re; double y=s.im;
scalar c(exp(x)*cos(y),exp(x)*sin(y));
return c;
}
Here is my main function:
int main()
{
scalar x(3,4);
scalar y=2;
cout << x*y << endl;
return 0;
}
This is is the output it is supposed to give:
6+8i
And this is the errors it gives instead:
In function 'std::ostream& operator<<(std::ostream&, const scalar&)':|
error: passing 'const scalar' as 'this' argument of 'double scalar::real()'
discards qualifiers|
And if I remove the const as the compiler says, I will get the following error:
error: no match for 'operator<<' in 'std::cout << scalar::operator*(const scalar&)
(((const scalar&)((const scalar*)(& y))))'|
The << operator can't handle the full expression - and why should it?
You need to implement the separate operators (operator+, operator*, ...) for your struct, which take your structs as parameters, do the corresponding operation on it, and return another of your structs. And only then define a operator<< taking a single one of your structs.
How would you even think of passing in such a complex structure to the operator<<, let alone parse it in there? Implement the separate operators, and leave the parsing to the compiler.
e.g. for a simple struct only encapsulating an int, doing that with + operation would look like this:
struct mystruct
{
int value;
};
then define:
mystruct const operator+(mystruct const & a, mystruct const & b)
{
mystruct result;
result.value = a.value + b.value;
return result;
}
and
std::ostream & operator<<(std::ostream& out, mystruct const & a)
{
out << a.value;
return out;
}
then you can do:
mystruct a, b;
a.value = 1;
b.value = 2;
std::cout << a+b;
Edit: With your updated code, there's exactly one problem:
std::ostream& operator<<(std::ostream&, const scalar&)
should be
friend std::ostream& operator<<(std::ostream&, const scalar&);
i.e. you're missing friend and an ;
Though the error you show suggests some different problem (which jrok's answer would have a solution for) - that doesn't seem to result from compiling the code you show! So please get the shown code and error message in sync.
The error is because functions scalar::real and scalar::imag are not const - you can only call const member functions when you've got a reference to a constant scalar.
double real() const {return re;}
double imag() const {return im;}
Why don't you just write std::cout << (x+y) << std::endl;
and be done?
As long as your overloaded operator takes its argument by value:
ostream& operator<<(ostream&, Thing)
or constant reference:
ostream& operator<<(ostream&, const Thing&)
you can use it for any expression with type Thing.
You should put parentheses around complex expressions, to avoid surprises from operator precedence; in particular, the second expression involving ^ won't be parsed as you expect.
You'll only be restricted to a single variable (or, more accurately, an lvalue expression) if the operator requires a non-constant reference; so don't do that.
UPDATE Now we've seen the code, the main issue is the in-class definition of operator<< as a member function; it can't be a member. Perhaps you want it to be a friend, so it can access im and re; or perhaps you should remove the declaration (making it a non-member, non-friend), and just use the public interface. If you do that, you'll need to add const to real() and imag(), so they can be called on a const object. You should do that anyway.
(Looking at the reported error, it seems you've already changed it to use the public interface, but haven't declared the necessary functions const).
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.
I have overloaded << in my code as a friend function. Even after using braces while cascading there is still the error
error: no match for ‘operator<<’ in ‘std::operator<< [with _Traits =
std::char_traits<char>]((* & std::cout), ((const char*)"complex conjugate is "))
<< c.myComplex::operator~()’
I have a class myComplex
class myComplex
{
private:
float real;
float imaginary;
public:
myComplex();
myComplex(float a,float b);
friend std::ostream& operator<<(std::ostream& iso,myComplex& a);
myComplex operator~() const;
};
The overload for <<, ~and the constructors are as follows,
std::ostream& operator<<(std::ostream& oso,myComplex& a)
{
oso<<a.real<<" + "<<a.imaginary<<"i"<<std::endl;
return oso;
}
myComplex myComplex::operator~() const
{
return myComplex(this->real,-1*this->imaginary);
}
myComplex::myComplex(float a,float b)
{
real = a;
imaginary = b;
}
I use it in main as follows,
Line 1: std::cout << "c is " << c << "\n";
Line 2: std::cout << "a is " << a << "\n";
Line 3: ((std::cout <<"complex conjugate is ")<<(~c))<<"\n";
Line 3: std::cout <<"complex conjugate is "<<~c<<"\n";
Line 1 and 2 work fine, but Line 3 gives the error. If it can cascade for Line 1 and 2 and since ~c also returns an ostream why does it give an error for that?
A temporary object (in this case that returned by operator~()) cannot be bound to a non-const reference. Change argument of operator<<() to be a const reference:
friend std::ostream& operator<<(std::ostream& iso,myComplex const& a);
Because your operator~() returns by value, you are feeding a temporary object into your ostream& operator<< here:
std::cout <<"complex conjugate is "<< ~c <<"\n";
// ^^ HERE! Temporary myComplex value.
The operator takes its 2nd argument by non-const reference myComplex&. A non-const reference cannot bind to a temporary. Change it to
std::ostream& operator<<(std::ostream& oso, const myComplex& a);
Use const myComplex & instead of myComplex &:
friend std::ostream& operator<<(std::ostream& iso, const myComplex& a);
^^^^^
And change the implementation, of course.
Your operator << takes the second parameter by non-const reference, which means it can't bind to a temporary (such as the one returned by ~). Change operator << to accept const myComplex& as the second argument.
It would certainly be weird if the stream-output operator modified its argument anyway.
BTW, do you know that C++ has a built-in class std::complex?