c++ undefined reference in extraction operator overloading - c++

Learning c++ bit by bit in codeblocks, I encountered this error. I have tried it for hours and saw various links but its still not working,
main.cpp
#include <iostream>
#include "Person.h"
using namespace std;
int main()
{
foo:: Person p;
//std:: cin >> p;
std:: cout << p;
return 0;
}
Person.h
#ifndef PERSON_H
#define PERSON_H
namespace foo{
class Person
{
public:
int age;
Person();
friend std:: ostream& operator << (std::ostream&,const Person&);
//friend std:: istream& operator << (std:: istream& in, Person& p);
protected:
private:
// std::string name;
};
}
#endif // PERSON_H
Person.cpp
#include <iostream>
#include "Person.h"
using namespace foo;
Person::Person()
{
age = 0;
//name = "noname";
}
std:: ostream& operator <<(std:: ostream& out, Person const &p)
{
out << "Extraction operator" << std:: endl << p.age << std:: endl;
// out << p.name << std::endl;
return out;
}
/*std:: istream& operator >>(std:: istream& in, Person &p)
{
in >> p.age >> p.name;
return in;
}*/
Q1. Why do we need to create the header file and Person.cpp in a seperate namespace?
Guess: Is it because cout would simply mean the global namespace and then we again have a overloaded cout so which definition is the compiler going to call its not sure?
Q2. By creating a object p of Person class in foo namespace in main and calling std:: cout << p, what are we trying to do? (std is in std namespace and we want to call the overloaded operator)
Error:
undefined reference to foo:: operator<<(std::ostream&, foo::Person const&)')
If we write the age in private it says that its is private but being a friend it should have access to private members. I know it's something related to namespace but I can't find out the reason.
no match for operator >> in std::cin
Earlier it was giving the above and many other error so I tried using two namespaces but still its not working.

You defined operator<< in the global namespace, but declared it inside namespace foo.
Define it inside the namespace foo:
namespace foo
{
// definition
}

I think you using wrong operator declaration
//friend std:: istream& operator << (std:: istream& in, Person& p);
instead of
friend std:: istream& operator >> (std:: istream& in, Person& p);
and also define your class methods in namespace where it were declared
#include <iostream>
#include "Person.h"
namespace foo
{
Person::Person()
{
age = 0;
//name = "noname";
}
std:: ostream& operator <<(std:: ostream& out, Person const &p)
{
out << "Extraction operator" << std:: endl << p.age << std:: endl;
// out << p.name << std::endl;
return out;
}
std:: istream& operator >>(std:: istream& in, Person &p)
{
in >> p.age >> p.name;
return in;
}
}
the code below runs perfectly on MS Visual C++
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <string>
namespace foo{
class Person
{
public:
Person();
friend std:: ostream& operator << (std::ostream&,const Person&);
friend std:: istream& operator >> (std:: istream& in, Person& p);
protected:
private:
int age;
std::string name;
};
}
namespace foo
{
Person::Person()
{
age = 0;
name = "noname";
}
std:: ostream& operator <<(std:: ostream& out, Person const &p)
{
out << "Extraction operator" << std:: endl << p.age << std:: endl;
out << p.name << std::endl;
return out;
}
std:: istream& operator >>(std:: istream& in, Person &p)
{
in >> p.age >> p.name;
return in;
}
}
int main()
{
foo:: Person p;
std:: cin >> p;
std:: cout << p;
_getch();
return 0;
}

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.

E0349 Error while Extending istream to support a Person class

I tried with and without #include <iostream> #include <string> or even using namespace std and nothing changed. The parameters must be references. When trying to run the code I receive the following error: E0349 no operator ">>" matches these operands in line 9.
#include <iostream>
#include <string>
#include "Person.h"
#include <cstdio>
using namespace std;
//Extending istream to support the Person class
std::istream & operator>>(std::istream & is, Person & p) {
is >> p.getName() >> p.getAge();
return is;
}
//Extending ostream to support the Person class
std::ostream & operator<<(std::ostream & os, Person & p) {
os << "[" << p.getName()<<"," << p.getAge()<<"]";
}
int main() {
Person *pOne = new Person();
cout << "Person1's name is: " << pOne->getName() << endl;
cin >> *pOne;
getchar(); //Just to leave the console window open
return 0;
}
Code from Person.h:
#pragma once
#include <iostream>
#include <string>
using namespace std;
class Person
{
private:
string name;
short age;
public:
Person();
virtual ~Person();
Person(string, short);
string getName();
short getAge();
};
And here the code from Person.cpp:
#include "Person.h"
#include <iostream>
#include <string>
using namespace std;
Person::Person()
:name("[Unassigned Name]"), age(0)
{
cout << "Hello from Person::Person" << endl;
}
Person::~Person()
{
cout << "Goodbye from Person::~Person" << endl;
}
Person::Person(string name, short age)
:name(name), age(age)
{
cout << "Hello from Person::Person" << endl;
}
string Person::getName()
{
return this->name;
}
short Person::getAge()
{
return this->age;
}
The first >> in line 9 right after is is underlined red. I'm using Visual Studio 2017 Community.
The problem is that operator>> needs something it can alter. The return value of a function like getName is not such a thing.
Here's how you normally do this which is to make operator>> a friend function so that it can directly access the internals of the Person class.
class Person
{
// make operator>> a friend function
friend std::istream & operator>>(std::istream & is, Person & p);
private:
string name;
short age;
public:
Person(string, short);
string getName();
short getAge();
};
//Extending istream to support the Person class
std::istream & operator>>(std::istream & is, Person & p) {
is >> p.name >> p.age;
return is;
}
Not the only way though. Here's another approach that doesn't need to make anything a friend function. It uses temporary variables and then makes and assigns a Person object from those temporary variables.
//Extending istream to support the Person class
std::istream & operator>>(std::istream & is, Person & p) {
string name;
short age;
is >> name >> age;
p = Person(name, age);
return is;
}

trouble overloading << operator, trouble printing vectors of objects

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.

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?

Simple questions about cin/cout overloading 4

#include <iostream>
#include <math.h>
#include <conio.h>
using namespace std;
class hugeint
{
public:
int size;
int number[100];
friend istream& operator>>(istream&,hugeint&);
friend ostream& operator<<(ostream&,hugeint&);
};
istream& operator>>(istream& in,hugeint& c)
{
// code not shown
return in;
}
ostream& operator<<(ostream& out,hugeint& c)
{
return out;
}
void main()
{
system( "color 70" );
hugeint o;
hugeint y;
hugeint z;
cin >> o;
cout<<"now y "<<endl;
cin>>y;
}
The compiler complains that operator >> is ambigious... what should I do ?
Nope, the code compiles.
However please note that I did also remove your extraneous and non-C++ headers, and fixed your incorrect main return type.
Try putting the operator<< and operator>> functions in the std namespace