"<<" Operator overloading error when defined outside main file - c++

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.

Related

"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.

error: no matching function for call to 'std::reference_wrapper<Medium>::reference_wrapper()

Book and Article are derived classes from Medium.
Why am I getting this error when trying to insert Medium / Book / Article in the bibliography?
error: no matching function for call to '**std::reference_wrapper<Medium>::reference_wrapper()**
main.cc
#include <iostream>
using namespace std;
#include "Bibliography.h"
#include "Medium.h"
#include "Book.h"
#include "Article.h"
int main()
{
Bibliography p(1);
Medium m1("PN","I","Pasol nah",2017);
p.insert(m1);
cout << p;
return 0;
}
Bibliography.h
#ifndef BIBLIOGRAPHY_H_
#define BIBLIOGRAPHY_H_
#include "Medium.h"
#include "Article.h"
#include "Book.h"
#include <iostream>
#include <functional>
#include <vector>
class Bibliography
{
private:
int m_Size;
std::vector<std::reference_wrapper<Medium>> v;
int index;
public:
Bibliography(int size);
void insert(Medium m);
friend std::ostream& operator<<(std::ostream& out, const Bibliography &b1);
};
#endif
Bibliography.cc
#include "Bibliography.h"
Bibliography::Bibliography(int size)
{
std::cout << "Bibliography created \n";
m_Size = size;
v.resize(m_Size);
index = 0;
}
void Bibliography::insert(Medium m)
{
v.push_back(m);
}
std::ostream& operator<<(std::ostream& out, const Bibliography &b1)
{
for (Medium &Medium : b1.v)
{
out << Medium.toString() << std::endl;
}
return out;
}
You should not use reference_wrapper in vector, because vector is restricted when using it with classes that do not have a default constructor. reference_wrapper doesn't have it, look at these constructors of reference_wrapper:
// initialization (1)
reference_wrapper (type& ref) noexcept;
reference_wrapper (type&&) = delete;
// copy (2)
reference_wrapper (const reference_wrapper& x) noexcept;
In this line
v.resize(m_Size);
you want to create m_Size reference_wrapperobjects, but the default constructor for reference_wrapper doesn't exist, and code cannot be compiled.
You can use reference_wrapper with vector but you will get a compilation error
when a method of vector is called, that needs the default constructor to be defined.

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.

Defining << operator at a base class

I'm trying to define the << operator for a base class, so I can later print the identifier of each object easily.
I have tried an SSCCE, but I don't really know where the problem is, since I'm printing a direction and not the content. I don't know if the problem appears by printing the vector position, or by printing the std::string(char[]).
main.cpp:
#include "City.h"
#include <vector>
#include <iostream>
int main() {
std::vector<Location*> locations;
locations.push_back(new City("TEST"));
for(unsigned int it = 0; it<locations.size(); it++){
std::cout << locations[it] << std::endl;
}
return 0;
}
Location.h:
#include <cstring>
#include <string>
class Location {
public:
Location(const std::string id);
friend std::ostream& operator<<(std::ostream& os, Location& loc);
std::string GetId();
private:
// Name/identifier of the location
char ID[5];
};
Location.cpp:
#include "Location.h"
Location::Location(const std::string id){
memset(this->ID, 0, 5);
strncpy(this->ID, id.c_str(), 5); // I have it as a char[5] at a larger app
}
std::string Location::GetId(){
return std::string(this->ID);
}
std::ostream& operator<<(std::ostream& os, Location& loc){
os << loc.GetId();
return os;
}
City.h:
#include "Location.h"
class City: public Location{
public:
City(std::string id);
};
City.cpp:
#include "City.h"
City::City(const std::string id) : Location(id){
}
Any idea?