I am trying overload the operator << but i keep having this error. I try doing research but with no result. I have a Point2D.h and a Point2D.cpp with a friend functions to overload. Below are my codes:
Point2D.h
#include <string>
#include <iomanip>
using namespace std;
#ifndef Point2D_H
#define Point2D_H
class Point2D
{
friend ostream& operator<< (ostream&, Point2D);
public:
Point2D();
Point2D(int, int);
protected:
int x;
int y;
};
Point.cpp
#include <string>
#include <cmath>
#include <iomanip>
#include "Point2D.h"
Point2D::Point2D() {
this->x=0;
this->y=0;
}
Point2D::Point2D(int x, int y) {
this->x=x;
this->y=y;
}
ostream& operator<< (ostream &out, Point2D pt)
{
out << "Point = " <<pt.x;
return out;
}
#endif
Below are my error message, not sure why there is no match for that method
Point2D.h: In function ‘std::ostream& operator<<(std::ostream&, Point2D)’:
Point2D.h:37:9: error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘int’)
out << pt.x;
^
Point2D.h:37:9: note: candidates are:
Point2D.h:35:10: note: std::ostream& operator<<(std::ostream&, Point2D)
ostream& operator<< (ostream &out, Point2D pt)
^
Point2D.h:35:10: note: no known conversion for argument 2 from ‘int’ to ‘Point2D’
In file included from Point2D.h:2:0,
from Point3D.h:2,
from Point3D.cpp:2:
/usr/include/c++/4.8/iomanip:235:5: note: template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, std::_Setw)
operator<<(basic_ostream<_CharT, _Traits>& __os, _Setw __f)
You need
#include <iostream>
Or at least
#include <ostream>
2 other advises:
the include guards (ifndef, define and endif) should be at the very beginning and at the very end of the header file (the endif MUST NOT be in the source file, but in the header file)
Adding using namespace std; in headers is bad practice. Use std:: prefix at least in the header. It's your choice if you'll use using namespace std; in the source. I wouldn't, but it's my personal choice.
You need to include another header
#include <iostream>
Only #include <ostream> will suffice though.
Correct code (see comments in code):
Point2D.h:
#include <string>
// #include <iomanip> // this includes io manipulators you do not need here
#include <iosfwd> // minimalist forward declarations for io streams
// using namespace std; // don't do this :(
#ifndef Point2D_H // should be above the includes
#define Point2D_H // should be above the includes
class Point2D
{
// friend ostream& operator<< (ostream&, Point2D);
friend std::ostream& operator<< (std::ostream&, const Point2D &);
// observe pass by const reference
Point2D.cpp
#include <string>
#include <cmath>
// #include <iomanip> // not needed
#include <iostream> // std::ostream class definition
#include "Point2D.h"
Point2D::Point2D() {
this->x=0;
this->y=0;
}
Point2D::Point2D(int x, int y) {
this->x=x;
this->y=y;
}
// ostream& operator<< (ostream &out, Point2D pt)
std::ostream& operator<< (ostream &out, const Point2D& pt)
{
out << "Point = " << pt.x;
return out;
}
// #endif // this shouldn't be here
First of all move directive
#endif
from the file Point.cpp to the end of the file Point2D.h
The files will look like
Point2D.h
#include <string>
#include <iomanip>
using namespace std;
#ifndef Point2D_H
#define Point2D_H
//...
#endif
Point.cpp
#include <string>
#include <cmath>
#include <iomanip>
#include "Point2D.h"
Point2D::Point2D() {
this->x=0;
this->y=0;
}
Point2D::Point2D(int x, int y) {
this->x=x;
this->y=y;
}
ostream& operator<< (ostream &out, Point2D pt)
{
out << "Point = " <<pt.x;
return out;
}
// #endif - removed
And substitute
#include <iomanip>
for
#include <iostream>
or at least add header
#include <iostream>
to the module file where the operator is defined.
Also the operator should be declared like
ostream& operator<< (ostream &out, const Point2D &pt);
Otherwise each time when the operator will be used a temporary object of type Point2D will be created.
Related
So, I have recently approched OOP in c++ through university and I found myself with a few problems.
I gave a shot at overloading the ostream operator << and found myself with some problems to solve.
First was that doing the overloading as ostream& operator<<(ostream& outs, const Test&); carries a problem described as \src\Test.h:15:48: error: 'std::ostream& test::Test::operator<<(std::ostream&, const test::Test&)' must take exactly one argument ostream& operator<<(ostream& outs, const Test&);, so, just like I did with the operator == removed the second argument. But once i Try to build the following code i get the error: \src\main.cpp:9:10: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&' cout << t;.
I read this error but can't comprhend it, what should I do and what is the mistake I'm doing?
Test.h
#include <iostream>
#include <cstring>
using namespace std;
#ifndef SRC_TEST_H_BECCIO
#define SRC_TEST_H_BECCIO
namespace test {
class Test {
private:
string mStr;
public:
Test(string str);
string getString(){return this->mStr;};
ostream& operator<<(ostream& outs);
};
} /* namespace test */
#endif /* SRC_TEST_H_BECCIO */
Test.cpp
#include "Test.h"
namespace test {
Test::Test(string str) {
this->mStr=str;
}
ostream& Test::operator<<(ostream& outs){
outs << this->getString()<<endl;
return outs;
}
} /* namespace test */
main.cpp
#include <iostream>
#include "Test.h"
using namespace std;
using namespace test;
int main() {
Test t("let's hope this goes well");
cout << t;
return 0;
}
It looks like the order of the arguments is backwards. See https://learn.microsoft.com/en-us/cpp/standard-library/overloading-the-output-operator-for-your-own-classes.
Try this declaration, and a similar implementation:
friend ostream& operator<<(ostream& os, Test t);
While doing some code practice myself I got some Error
student.h file
#pragma once
class Student {
public:
Student() = default;
Student(int id, const char* name, int score);
Student(const Student& s);
Student(Student&& other);
Student& operator=(Student&& other);
virtual ~Student();
**friend std::ostream & operator<<(std::ostream & os, const Student & rhs);**
void print();
private:
int mId;
char* mName;
int mScore;
size_t mSize;
};
student.cpp file
#include "student.h"
#include <iostream>
#include <string>
... //bunch of constructors, override...
std::ostream & operator<<(std::ostream& os, const Student & rhs)
{
os << rhs.mId << rhs.mName << rhs.mScore ; // Compile Error: Cannot Access Student Member(rhs.mId, rhs.mName...)
return os;
}
The Error i got was i cannot access Student class member despite I declared it friend function in student.h
Strange to me, It compiled successfully if i declare #include<iostream> statement in student.cpp file like this
#include <iostream> //change position <iostream> and "student.h"
#include <string>
#include "student.h"
... //bunch of constructors, override...
std::ostream & operator<<(std::ostream& os, const Student & rhs)
{
os << rhs.mId << rhs.mName << rhs.mScore ; //Compile successfully
return os;
}
So, why #include statement sequences are matters? i thought #include statement just copy-paste to my cpp file.
And it also compiled successfully when i declare #include<iostream> to student.h,
so when i include some #include things the Best-case is declare it to header-file?
Could you give me some advise?
I compiled my program in Visual Studio 2019.
In student.h add an include for iosfwd:
#pragma once
#include <iosfwd>
class Student ...
This will ensure correct resolution of the std::ostream symbol and recognize the ostream operator you defined as the one you declared as a friend.
The iosfwd header contains forward declarations of the symbols in iostream header, and it is defined for exactly this scenario.
In C++ we must declare anything before using it.
So your problem is that you haven't declared std::ostream but you have used it in student.h.
An suitable solution is to #include <iostream> in the beginning of student.h, below #pragma once.
You can also put these before class Stduent:
namespace std
{
class ostream;
}
This is called forward declaration.
I tried to overload the << operator and wanted to use it in the main function. However, I get the following compiler error:
main.cpp:14:19: error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘const Point’)
std::cout << point;
~~~~~~~~~~^~~~~~~~
Interestingly, if I put all the code into a single file, it works just fine.
The code looks as follows:
main.cpp
#include <vector>
#include <iostream>
#include "data.hpp"
int main() {
const unsigned int n_points = 10;
Data data (n_points);
std::vector<Point> d;
d = data.get();
for (const auto& point : d){
std::cout << point;
}
return 0;
}
data.cpp
#include <cmath>
#include <algorithm>
#include "data.hpp"
Data::Data (unsigned int _n_samples) {
n_samples = _n_samples;
data.resize(n_samples, {4.0, 2.0});
}
std::vector<Point> Data::get(){
return data;
}
std::ostream& operator<<(std::ostream& out, const Point& point){
out << point.x << " " << point.y << '\n';
return out;
}
data.hpp
#ifndef DATA_H
#define DATA_H
#include <ostream>
#include <vector>
struct Point {
double x;
double y;
};
class Data {
public:
Data (unsigned int);
unsigned int n_samples;
std::vector<Point> get();
friend std::ostream& operator<<(std::ostream& out, const Point& point);
private:
std::vector<Point> data;
};
#endif /* DATA_H */
Can someone please tell me why this error occurs?
main() has no idea about your operator<< because you did not declare it in data.hpp in a scope where main() can find it. It needs to be declared as a free-floating function, not as a friend of the Data class, eg:
#ifndef DATA_H
#define DATA_H
#include <ostream>
#include <vector>
struct Point {
double x;
double y;
};
std::ostream& operator<<(std::ostream& out, const Point& point); // <-- moved here
class Data {
public:
Data (unsigned int);
unsigned int n_samples;
std::vector<Point> get();
private:
std::vector<Point> data;
};
#endif /* DATA_H */
It worked in one file because you put the definition of operator<< before main – if you move it to after main, you will encounter the same error.
The friend declaration does not add the declaration of the operator to the global scope, and there is no point in making it a friend of Data.
Header file:
#ifndef CART_H
#define CART_H
#include "Tops.h"
#include <iostream>
#include <vector>
using namespace std;
class Cart
{
public:
Cart();
void addTop(Tops& top);
friend ostream& operator<<(ostream& ostr, const Cart& c);
private:
vector<Tops> tops;
};
#endif
Implementation file:
#include "Cart.h"
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
Cart::Cart() { }
void Cart::addTop(Tops &top)
{
tops.push_back(top);
}
ostream& operator<<(ostream &ostr, const Cart &c)
{
ostr << "TOPS IN CART:\n-------------\n";
for (auto const top : c.tops) {ostr << top << endl; } // no match for 'operator<<'
return ostr;
}
Problem: I keep getting a "no match for operator<<" error and I have no idea why, and I also have no idea what it means. When I google this error, what has caused the error in other people's codes does not apply to mine.
In your declaration you have stated that the Cart argument will be const:
friend ostream& operator<<(ostream& ostr, const Cart& cart);
but your definition does not:
ostream& operator<<(ostream &ostr, Cart &c)
They need to match (either both const or both not - both const would be right here) for the friend declaration to be of any use.
Disclaimer: I'm new to programming in c++, I've read through dozens of forums, and can't find an answer to my specific question.
I've included the header and definition files for a Point class below and a main function that calls an overloaded ostream to print the Point. I can't find the correct syntax for the definition for the non member overloaded operator<<. If I have it the way it's posted, I get error message:
undefined reference to `Clustering::operator<<(std::ostream&, Clustering::Point const&)
If I add Clustering:: before the operator<< I get error message:
std::ostream& Clustering::operator<<(std::ostream&, const Clustering::Point&)' should have been declared inside 'Clustering'
std::ostream &Clustering::operator<<(std::ostream &os, const ::Clustering::Point &point)
How is this code supposed to be written?
Point.h file:
#ifndef CLUSTERING_POINT_H
#define CLUSTERING_POINT_H
#include <iostream>
namespace Clustering {
class Point {
int m_dim; // number of dimensions of the point
double *m_values; // values of the point's dimensions
public:
Point(int);
friend std::ostream &operator<<(std::ostream &, const Point &);
};
}
#endif //CLUSTERING_POINT_H
Point.cpp file:
#include "Point.h"
//Constructor
Clustering::Point::Point(int i)
{
m_dim = i;
m_values[i] = {0};
}
std::ostream &operator<<(std::ostream &os, const Clustering::Point &point) {
os << "Test print";
return os;
}
Main.cpp:
#include <iostream>
#include "Point.h"
using namespace std;
using namespace Clustering;`
int main() {
Point p1(5);
cout << p1;
return 0;
}
You need to put your std::ostream &operator<< in Clustering namespace in Point.cpp
namespace Clustering {
std::ostream &operator<<(std::ostream &os, const Clustering::Point &point)
{
// ...
}
}