Error when overloading operator<<, "cannot overload functions distinguished by return type alone"

Viewed 271

I'm parsing two text files that describe tests. For that purpose, I have two structs to hold test instances:

struct testcase_xy {
public:
    testcase_xy() = default;
    testcase_xy(float x_, float y_, float yaw_, float pitch_) :x(x_), y(y_), yaw(yaw_), pitch(pitch_) {}
    friend std::ifstream& operator>> (std::ifstream& in, testcase_xy& t);
    friend std::ostream& operator<< (std::ostream& out, const testcase_xy& t);


    float x = 0;
    float y = 0;
    float yaw = 0;
    float pitch = 0;
};

struct testcase_mat {

    testcase_mat() : pitch(0), yaw(0) { mat.resize(9); }
    testcase_mat(float p, float y, std::vector<float> m) : pitch(p), yaw(y), mat(m) {}

    friend std::ifstream& operator>> (std::ifstream& in, testcase_mat& m);
    friend std::ofstream& operator<< (std::ostream& out, const testcase_mat& m);

    float pitch = 0;
    float yaw = 0;
    std::vector<float> mat;
};

Later in the file, I declare operator>> and operator<< to read from file and output to std::cout, for both structs.

std::ifstream& operator>> (std::ifstream& in, testcase_xy& t)
{
    in >> t.x >> t.y >> t.yaw >> t.pitch;
    return in;
}

std::ostream& operator<< (std::ostream& out, const testcase_xy& t) {
    out << "testcase xy x: " << t.x << " y: " << t.y << " yaw: " << " " << t.yaw << " pitch: " << t.pitch << std::endl;
    return out;
}

std::ifstream& operator>> (std::ifstream& in, testcase_mat& m)
{
    in >> m.pitch >> m.yaw;
    float value;
    for (int i = 0; i < 9; ++i) {
        in >> value;
        m.mat.push_back(value);
    }
    return in;
}

std::ostream& operator<< (std::ostream& out, const testcase_mat& m) {
    out << "testcase m: pitch: " << m.pitch << " yaw: " << m.yaw << std::endl;
    for (int i = 0; i < 9; ++i)
        out << m.mat[i] << std::endl;
    return out;
}

However, the compiler gives a compilation error:

cannot overload functions distinguished by return type alone

I don't understand why, since the operator>> and operator<< that I overload for each of the structs have different parameter types, since the structures are of different type.

What's going on?

1 Answers

Inside the structure:


struct testcase_mat { 
    // [...]
    friend std::ifstream& operator>> (std::ifstream& in, testcase_mat& m);
    friend std::ofstream& operator<< (std::ostream& out, const testcase_mat& m);
           ^^^^^^^^^^^^^
};

Outside:

std::ostream& operator<< (std::ostream& out, const testcase_mat& m) { /* [...]*/ }
^^^^^^^^^^^^^

These inconsistent return types, with consistent parameter types, are leading to your error.

You should make all the return types consistent.

I recommend using std::ostream and std::istream (without the f) to define these functions. These should automatically work with std::ofstream instances (because of the inheritance structure), and would also work with std::ostringstream instances, e.g. in unit testing.

Related