trouble overloading << operator, trouble printing vectors of objects - c++

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.

Related

error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'

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);

I'm newbie in c++, got unexpected error while <<operator Overloading. Could you tell me some advise?

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.

"no match for ‘operator>>’" while using stringstream with operator overloading in a class inside a namespace

I'm trying to overload the >> operator in a class inside a namespace, but as soon as I try to use it with a string stream it doesn't work. Here's a distilled version of my code:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
namespace Foo {
class Bar {
public:
string str;
friend istream& operator >>(istream& in, Bar& t);
};
}
inline istream& operator >>(istream& in, Foo::Bar& t) {
in >> t.str;
return in;
}
int main() {
Foo::Bar foo;
stringstream("foo") >> foo;
cout << foo.str << endl;
return 0;
}
and here's the error:
main.cpp:22:22: error: no match for ‘operator>>’ (operand types are ‘std::stringstream {aka std::__cxx11::basic_stringstream<char>}’ and ‘Foo::Bar’)
The thing is these other ways of doing it work:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
namespace Foo {
class Bar {
public:
string str;
friend istream& operator >>(istream& in, Foo::Bar& t) {
in >> t.str;
return in;
}
};
}
int main() {
Foo::Bar foo;
stringstream("foo") >> foo;
cout << foo.str << endl;
return 0;
}
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Bar {
public:
string str;
friend istream& operator >>(istream& in, Bar& t);
};
inline istream& operator >>(istream& in, Bar& t) {
in >> t.str;
return in;
}
int main() {
Bar foo;
stringstream("foo") >> foo;
cout << foo.str << endl;
return 0;
}
The thing is, I have no idea why the first way of doing it should be wrong. I'm using the g++ compiler on linux if that helps. Could someone help me understand what's going on?
Thanks to hints from Sam Varshavchik (in the comments above), I've been able to come up with a correct version of the first version:
#include <iostream>
#include <string>
#include <sstream>
namespace Foo {
class Bar {
public:
std::string str;
friend std::istream& operator >>(std::istream& in, Bar& t);
};
std::istream& operator >>(std::istream& in, Bar& t);
}
std::istream& Foo::operator >>(std::istream& in, Foo::Bar& t) {
in >> t.str;
return in;
}
using namespace std;
int main() {
Foo::Bar foo;
stringstream("foo") >> foo;
cout << foo.str << endl;
return 0;
}
The key was making sure that the operator>> function was both declared and defined in the same scope. I still wanted to be able to define the function outside of the namespace braces, so I had to add a declaration inside the namespace so the compiler would know that there's supposed to be that function in the namespace. Keeping the function definition separate allowed me to separate my code into three files, main.cpp, foo.hpp, and foo.cpp:
// main.cpp
#include <iostream>
#include <string>
#include <sstream>
#include "foo.hpp"
using namespace std;
int main() {
Foo::Bar foo;
stringstream("foo") >> foo;
cout << foo.str << endl;
return 0;
}
// foo.hpp
#ifndef FOO_HPP
#define FOO_HPP
#include <string>
#include <iostream>
namespace Foo {
class Bar {
public:
std::string str;
friend std::istream& operator >>(std::istream& in, Bar& t);
};
std::istream& operator >>(std::istream& in, Bar& t);
}
#endif
// foo.cpp
#include "foo.hpp"
std::istream& Foo::operator >>(std::istream& in, Foo::Bar& t) {
in >> t.str;
return in;
}
Anyways, thanks so much for the help! And thanks for not hand-feeding me a solution; it's so much better to learn by figuring it out myself, even if I did get some help pointing me in the right direction.

Implement a non-member, overloaded operator, in a namespace, with correct syntax

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)
{
// ...
}
}

c++ friend overloading operator <<

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.