Search code examples
c++vectorstreamostreamistream

C++ overloading the ostream and istream operators


The aim of this code is to read the file containing the name, dollars in billions and the country which are separated by tabs. I need to create a class Billionaire and overload the ostream and istream operators to conveniently read the file into a vector and write the content to the output. And then create a map which maps the country string to a pair. The pair contains a copy of the first billionaire of every country from the list and a counter to count the number of billionaires per country. However, I cannot overload stream and stream operators.

I've tried to overload these operators in Billionaire class but I am ending up with errors.

#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <set>
#include <map>
#include <string>
#include <iterator>
#include <fstream>
#include <istream>
#include <ostream>

using namespace std;

class Billionaire{
    //overload the ostream and istream operators to conveniently
    //read the  file into a vector and write the content to the output

public :

    friend ostream &operator<<(ostream &stream, Billionaire o);
    friend istream &operator>>(istream &stream, Billionaire &o);
};

int main(){

    std::ifstream stream("Forbes2018.txt");

    if(!stream){

        cout << " WARNING : File not found !" << endl ;

    }

    vector <Billionaire> billionaires;
    copy (istream_iterator<Billionaire>( stream ),
          istream_iterator<Billionaire>() , back_inserter( billionaires ));
    copy (billionaires.begin () , billionaires.end () ,
          ostream_iterator < Billionaire >( cout , "\n"));

    map < string , pair < const Billionaire , size_t >> m;

}

I am having 2 errors: :-1: error: symbol(s) not found for architecture x86_64 :-1: error: linker command failed with exit code 1 (use -v to see invocation)


Solution

  • Your overload attempt is a good start: you have announced to the compiler that there will be an overload:

    friend ostream &operator<<(ostream &stream, Billionaire o);
    friend istream &operator>>(istream &stream, Billionaire &o);
    

    Unfortunately, something is missing. This is what the linker message says. You still need to tell the compiler how this overload looks like:

    ostream &operator<<(ostream &stream, Billionaire o) {
         // put your code here
         ...
         return stream;
    }
    istream &operator>>(istream &stream, Billionaire &o) {
         // put your code here
         ...
         return stream;
    }
    

    In case you have defined these operators in the Billionaire, the compiler wont be able to use them here : in main you invoke the free standing operator (that you have declared as friend), whereas you would have defined class members that have to be invoked on a Billionaire with the . or -> operator and have a different signature than what you’re using in main.