Gilfoyle
Gilfoyle

Reputation: 3616

"<<" Operator overloading error when defined outside main file

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?

Upvotes: 0

Views: 35

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 595402

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 */

Upvotes: 2

molbdnilo
molbdnilo

Reputation: 66371

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.

Upvotes: 2

Related Questions