0

I'm quite new to c++ and my current problem is to output a struct using an overloaded operator. I've tried my best, but apparently it is not enough. Anyone knows why my compiler keeps pushing out this mistake: \main.cpp|16|error: no match for 'operator<<' (operand types are 'std::basic_ostream' and 'const Eyecolor')|

This is the corresponding code:

#include <iostream>
#include <string>
using namespace std;

enum class Eyecolor {blue, brown, green};

struct PStruct {
    string surname;
    Eyecolor eyecolor;
    double height;
    bool gender;
    friend std::ostream& operator<<(std::ostream& os, const PStruct& ps);
};
std::ostream& operator<<(std::ostream& os, const PStruct& ps)
{
    os << ps.surname << '/' << ps.height << '/' << ps.gender << '/' << ps.eyecolor; //line 16
    return os;
}
void print(){
    cout << os;
}

int main()
{
    return 0;
}

I'm pretty sure i defined the operator<< one line prior to that.

Anyway thanks for the answers in advance

maku2207
  • 1
  • 1
  • 7
    You did not define the `operator<<` for your `enum Eyecolor` – pptaszni May 05 '21 at 11:47
  • E.g. exactly what the error states. `(operand types are 'std::basic_ostream' and 'const Eyecolor')` .You defined your operator on `PSStruct`. But your enum is a class-type. It needs its own operator if you want `<< ps.eyecolor` to work. – WhozCraig May 05 '21 at 11:50
  • Well either as WhozCraig said, or you can make a switch(or if) instead of "<< ps.eyecolor", like: https://godbolt.org/z/TEf8bds8v – MathiasJ May 05 '21 at 11:52
  • 1
    @MathiasJ; 1) your example is broken. 2) bad advice. – user1810087 May 05 '21 at 12:39
  • @user1810087 yes, because the example code given is broken? The question was related to a specific compiler error, this code fixes that compiler error. It does not fix that "void print(){ cout << os; }" is not compliable code, but no questions was asked in regards to that. – MathiasJ May 05 '21 at 13:06

1 Answers1

0

A stripped down version of the error message:

no match for 'operator<<' (operand types are 'std::ostream' and 'const Eyecolor')
                                          ----------------------------> ^^ 

The error complains about missing operator<< for Eyecolor. The one you defined is for PStruct and tries to call the missing operator here:

os << ps.surname << '/' << ps.height << '/' << ps.gender << '/' << ps.eyecolor;
                                          --------------------> ^^

In the same way you defined one for PStruct you need to define one for EyeColor.

Enum to string conversion is a long standing annoyance in C++, you can see how much work one has to put into it to get a generic solution here: enum to string in modern C++11 / C++14 / C++17 and future C++20. Here I am not going into that, but merely show how to get the operator<< working.

Really no offense, but making the operator a friend smells like Cargo Cult Programming. You probably have seen this in examples, and commonly the operator needs to be befriended, but there is no reason to do so in your code. Moreover print() has errors.

A fixed version could look like this:

#include <iostream>
#include <string>

enum class Eyecolor {blue, brown, green};

struct PStruct {
    std::string surname;
    Eyecolor eyecolor;
    double height;
    bool gender;
};
std::ostream& operator<<(std::ostream& os, const Eyecolor ec){
    switch(ec){
        case Eyecolor::blue :
            os << "blue";
            break;
        case Eyecolor::brown :
            os << "brown";
            break;
        case Eyecolor::green :
            os << "green";
            break;
        default:
            os << "unknown color";
    }
    return os;
}

std::ostream& operator<<(std::ostream& os, const PStruct& ps)
{
    os << ps.surname << '/' << ps.height << '/' << ps.gender << '/' << ps.eyecolor;
    return os;
}
void print(const PStruct& ps){
    std::cout << ps;
}

PS: Why is “using namespace std;” considered bad practice?

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185