“<<”在主文件外部定义时出现运算符重载错误

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

我试图重载 << 运算符并想在主函数中使用它。但是,我收到以下编译器错误:

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;
         ~~~~~~~~~~^~~~~~~~

有趣的是,如果我将所有代码放在一个文件中,它就可以正常工作。

代码如下所示:

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

谁能告诉我为什么会出现这个错误?

它在一个文件中工作,因为你把 operator<< 的定义放在 main 之前——如果你把它移到 main 之后,你会遇到同样的错误。
友元声明并没有将运算符的声明添加到全局范围,使它成为 Data.

的友元没有意义

main() 不知道您的 operator<<,因为您没有在 data.hpp 中声明它在 main() 可以找到它的范围内。它需要声明为自由浮动函数,而不是 Data class 的 friend,例如:

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