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;
}
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 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.)
I guess this is a n00b question because I couldn't find anything about it on web...
Here is Point class:
class Point {
public:
Point();
Point(double x, double y);
double getX() const;
double getY() const;
void setX(double);
void setY(double);
friend std::ostream& operator<<(std::ostream& os, const Point& obj);
private:
double x;
double y;
};
And here is an implementation of operator<< function:
inline std::ostream& operator<<(std::ostream& os, const Point& obj) {
os << "(" << obj.getX() << "," << obj.getY() << ")";
return os;
}
Now, in main function I have Point *p;... How can I print it using std::cout?
You need to dereference your pointer but as pointers can be null, you should check first.
if( p != nullptr )
std::cout << *p << std::endl;
or even just
if( p )
std::cout << *p << std::endl;
And now, go and read this in our community wiki, hopefully it will provide you the answers.
What are the differences between a pointer variable and a reference variable in C++?
So, I finally found out where was the problem.
Although all tutorials, books and even c++ reference agree that inline directive can be ignored by the compiler, it turns out that when I remove inline keyword from implementation of an overloaded function everything works.
I overloaded a cout and cin opeartor and when I tried to use it, it gave me an error like this:
1 IntelliSense: function "std::basic_ostream<_Elem, _Traits>::basic_ostream(const std::basic_ostream<_Elem, _Traits>::_Myt &)
[with _Elem=char, _Traits=std::char_traits<char>]"
(declared at line 84 of "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\ostream") cannot be referenced -- it is a deleted function
And here's the header file of my class:
#pragma once
#include <iostream>
class Point2D
{
private:
int m_X;
int m_Y;
public:
Point2D(): m_X(0), m_Y(0)
{
}
Point2D(int x, int y): m_X(x), m_Y(y)
{
}
friend std::ostream& operator<< (std::ostream out, const Point2D &point)
{
out << "(" << point.m_X << "," << point.m_Y << ")" << std::endl;
return out;
}
friend std::istream& operator>> (std::istream in, Point2D &point)
{
in >> point.m_X;
in >> point.m_Y;
return in;
}
int getX() const { return m_X; }
int getY() const { return m_Y; }
~Point2D();
};
So, basically, it's just a class that can return and set X and Y coordinates. And I overwrote << and >> operators to make things easier.
But when I try to use it in the main function like this:
#include "stdafx.h"
#include <iostream>
#include "Point2D.h"
using namespace std;
int main(int argc, char * argv[])
{
Point2D point(7, 7);
cout << point; //there's an error here.
return 0;
}
There seems to be the error on this line:
cout << point;
What exactly am I doing wrong?
The error message says ostream cannot be copied.
friend std::ostream& operator<< (std::ostream out, const Point2D &point)
{
...
std::ostream out is pass-by-value: When the operator << is called, compiler tries to copy the argument. However, std::ostream cannot be copied, so compilation is failed.
You should use reference.
friend std::ostream& operator<< (std::ostream &out, const Point2D &point)
{
...
friend std::istream& operator>> (std::istream &in, Point2D &point)
{
...
(Even if you're using some classes which provides copying, you shouldn't usually use pass-by-val. Copying some objects is so expensive;)
Just had the same problem. For other peoples looking for a solution. The error
function "std::basic_ostream<_Elem, _Traits>::basic_ostream(const std::basic_ostream<_Elem, _Traits> &) [with _Elem=char, _Traits=std::char_traits<char>]" (declared at line 83 of "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.15.26726\include\ostream") cannot be referenced -- it is a deleted function
comes from the line:
std::ostream& operator<< (std::ostream os, const Point2D &point)
correct it to this and it should be fine:
std::ostream& operator<< (std::ostream &os, const Point2D &point)
The problem here is with the arguments
friend std::ostream& operator<< (std::ostream out, const Point2D &point)
The input argument out is pass-by-value. When the compiler tries to copy the std::ostream variable by value it fails and thus the error. Pass the variable out by reference as shown below and it should clear the error. Also, the return type is pass-by-reference, so by doing the below change your are returning the same object and not creating a new copy.
friend std::ostream& operator<< (std::ostream &out, const Point2D &point)
Useful link: How to properly overload the << operator for an ostream?
I'm working through some home work and having problems with how to form my method signature for overloading a member of a class.
My header file
class MyInt
{
int internalInt;
public:
MyInt::MyInt(int i);
const MyInt operator+(const MyInt& mi);
const MyInt& operator++();
};
My code file
MyInt::MyInt(int i)
{
internalInt = i;
}
const MyInt MyInt::operator+(const MyInt& mi)
{
cout << "Inside the operator+\n";
mi.print(cout);
return MyInt(internalInt + mi.internalInt);
}
const MyInt& MyInt::operator++()
{
cout << "Inside the operator++\n";
internalInt++;
return this; //Line 42
}
When I try to compile the code I'm getting an error that says
ex4.cpp:42: error: invalid initialization of reference of type ‘const MyInt&’
from expression of type ‘MyInt* const’
I'm having problems understanding how to get this working and have tried a few method signatures. In my text book they are in lining all the overloads but I was hoping to figure out what I'm doing wrong instead of just going with the flow to get my code to compile.
Thanks!
try:
const MyInt& MyInt::operator++()
{
cout << "Inside the operator++\n";
internalInt++;
return *this;
}
You are returning the this pointer, not the reference, you need to dereference it.
First of all, in operator++(), write return *this; instead of return this;. Also remove the const!
-
const MyInt operator+(const MyInt& mi);
Second, Make it const-function, as
const MyInt MyInt::operator+(const MyInt& mi) const // <--- note this!
This is const-function. Without it, you would not be able to add const objects of MyInt.
After you write const on the right most side, you can write this:
const MyInt m1(10);
MyInt m2(20);
MyInt m3 = m1 + m2 ; //m1 is const, so it can call ONLY const-function