Operator overloading<< to a class

Hey! I want to overload the operator to a class. But it doesn't seem to work. Cool if someone could help. I'll post the relevant code to the question below.
Sorry for the long code, but I can't find the error. The error code most of the time is this: "Invalid operands to binary expression".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

enum class Campus
{};

class Meeting
{
private:
    int day;
    int startTime;
    int endTime;
    Campus location;
    string subject;
    const Person* leader;
    set<const Person*> participants;
    static set<const Meeting*> meetings;
    
public:
    Meeting(int day, int startTime, int endTime, Campus location, string subject, const Person* leader);
    int getDay() const;
    int getstartTime() const;
    int getendTime() const;
    Campus getLocation() const;
    string getSubject() const;
    const Person* getLeader();
    void addParticipants(const Person* p);
    vector<string> getParticipantList() const;
    ~Meeting();
    vector<const Person*> findPotentialCoDriving();
};

int Meeting::getstartTime() const
{
    return startTime;
}
int Meeting::getendTime() const
{
    return endTime;
}

Campus Meeting::getLocation() const
{
    
    return location;
    
}

string Meeting::getSubject() const
{
    return subject;
}

const Person* Meeting::getLeader()
{
    return leader;
}

vector<string> Meeting::getParticipantList() const
{
    
    vector<string> names;
    
    for ( const Person* p : participants ) //auto& p er det samme, men det auto gjør er å finne ut at dette er en const Person*.
    {
        
        names.push_back((*p).getName());
        //names.push_back(p->getName()); En annen måte å skrive på, men det gjør akkurat det samme.
        
    }
    
    return names;
}

//Operator overloading function which is not a friend of the class. 
ostream& operator<<(ostream& output, const Meeting &meeting)
{
    
    //output << "Leder: " << p.getLeader() << endl;
    output << "Starttmime: " << meeting.getstartTime() << endl;
    output << "Endtime: " << meeting.getendTime() << endl;
    output << "Subject: " << meeting.getSubject() << endl;
    output << "Location: " << meeting.getLocation() << endl;
    
    for (auto &p : meeting.getParticipantList() )
    {
        output << "List of participants: " << endl;
        output << p << endl;
        
    }
    return output;
}

1
2
3
Campus Meeting::getLocation() const
// ....
    output << "Location: " << meeting.getLocation() << endl;


You haven't defined what << does for a "Campus".
Thanks! Can I do that inside the getLocation() function and how do I do it?

Even if I remove the getLocation() part from the overloading operator function the program won't execute with the same written in main. So it can't be the only problem.
Last edited on
You haven't shown main(), so we have no idea what problems will arise there.


theredp wrote:
Can I do that inside the getLocation() function

No


theredp wrote:
how do I do it?

Well, your enum class Campus is empty, so nobody knows.
1
2
enum class Campus
{};

Why do you want to use an enum here?

Your strongly typed enumeration is still an int:
1
2
// brutal -------------------------\/
output << "Location: " << static_cast<int>(meeting.getLocation()) << endl;
The Campus is changed to:

enum class Campus
{Trondheim, Gjøvik, Ålesund};

I made this function to get a string:
string getCampusString(Campus a)
{
switch (a)
{
case Campus::Trondheim:
return "Trondheim";
break;
case Campus::Gjøvik:
return "Gjøvik";
break;
case Campus::Ålesund:
return "Ålesund";
break;

default:
return "Not a campus";
break;
}

}

So my overloader of the operator now looks like this:
ostream& operator<<(ostream& output, const Meeting& meeting)
{

output << "Leader: " << *(meeting.getLeader()) << endl;
output << "Starttime: " << meeting.getstartTime() << endl;
output << "Endtime: " << meeting.getendTime() << endl;
output << "Subject: " << meeting.getSubject() << endl;
output << "Location: " << getCampusString(meeting.getLocation()) << endl;
output << "List of participants: " << endl;

for (string person : meeting.getParticipantList() )
{
output << person << endl;

}
return output;
}

Main looks like this:
int main() {
Car g{3};
Car l{2};
Car p{4};

Person gunnar("Gunnar", "[email protected]", &g);
Person lars("Lars", "[email protected]", &l);
Person pernille("Pernille", "[email protected]", &p);

Meeting meeting(1,10,12,Campus::Trondheim,"Mathematics 1", &gunnar);

meeting.addParticipants(&lars);
meeting.addParticipants(&pernille);


cout << meeting; //Here i get the error code: Invalid operands to binary expression ('std::__1::ostream' (aka 'basic_ostream<char>') and 'Meeting'). Why is this wrong?

}
Was that your only error message?

output << "Leader: " << *(meeting.getLeader()) << endl;
Have you defined an overloaded << operator for a Person (which is the result of *meeting.getLeader())?
Yes, it's the only error code and << is overloaded for a Person.
Please show your ENTIRE code ... IN CODE TAGS.

Impossible to debug without seeing it.
Incredible messy but they are belonging in different h. files.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
class Car
{
private:
    int freeSeats;
    
    
public:
    int getFreeSeats() const;
    bool hasFreeSeats() const;
    void reserveFreeSeat();
    Car(int freeSeats);
    
};

Car::Car(int freeSeats)
: freeSeats(freeSeats)
{};

int Car::getFreeSeats() const{
    return freeSeats;
}

bool Car::hasFreeSeats() const
{
    if (freeSeats == 0)
        return false;
    else
        return true;
    
}

void Car::reserveFreeSeat()
{
    
    freeSeats--;
    
}

class Person
{
private:
    string name;
    string email;
    Car* car;
    
public:
    Person(string navn, string epost, Car* bil = nullptr);
    string getName() const;
    string getEmail() const;
    void setEmail(string mailname);
    bool hasAvailableSeats() const;
    friend ostream& operator<<(ostream& output, const Person &p);
    
};

Person::Person(string name, string email, Car* car)
: name(name), email(email), car(car)
{};

string Person::getName() const
{
    
    return name;
    
}

string Person::getEmail() const
{
    
    return email;
    
}

void Person::setEmail(string mailname)
{
    
    email = mailname;
    
}

bool Person::hasAvailableSeats() const
{
    
    if (car->hasFreeSeats())
        return true;
    else
        return false;
}

//Overlasting av output parameter. Ikke en friendfunksjon av klassen. 
ostream& operator<<(ostream& output, const Person &p)
{
    string available = "Ingen ledige seter i bilen.";
    if ( p.hasAvailableSeats() )
        available = "Ledige seter i bilen.";
    
    output << "Navn: " << p.name << endl;
    output << "Email: " << p.email << endl;
    output << "Bil: " << available << endl;
    
        
    
    return output;

enum class Campus
{Trondheim, Ålesund, Gjøvik};

string getCampusString(Campus a)
{
    switch (a)
    {
        case Campus::Trondheim:
            return "Trondheim";
            break;
        case Campus::Gjøvik:
            return "Gjøvik";
            break;
        case Campus::Ålesund:
            return "Ålesund";
            break;
            
        default:
            return "Not a campus";
            break;
    }
    
}

class Meeting
{
private:
    int day;
    int startTime;
    int endTime;
    Campus location;
    string subject;
    const Person* leader;
    set<const Person*> participants;
    static set<const Meeting*> meetings;
    
public:
    Meeting(int day, int startTime, int endTime, Campus location, string subject, const Person* leader);
    int getDay() const;
    int getstartTime() const;
    int getendTime() const;
    Campus getLocation() const;
    string getSubject() const;
    const Person* getLeader() const;
    void addParticipants(const Person* p);
    vector<string> getParticipantList() const;
    ~Meeting();
    vector<const Person*> findPotentialCoDriving();
    
};

nt Meeting::getDay() const
{
    return day;
}

int Meeting::getstartTime() const
{
    return startTime;
}
int Meeting::getendTime() const
{
    return endTime;
}

Campus Meeting::getLocation() const
{
    
    return location;
    
}

string Meeting::getSubject() const
{
    return subject;
}

const Person* Meeting::getLeader() const
{
    return leader;
}

void Meeting::addParticipants(const Person* p)
{
    
    participants.insert(p);
    
}

set<const Meeting*> Meeting::meetings;

Meeting::Meeting(int day, int startTime, int endTime, Campus location, string subject, const Person* leader)
: day(day), startTime(startTime), endTime(endTime), location(location), subject(subject), leader(leader)
{
    cout << "Konstruktøren har blitt kjørt." << endl;
    participants.insert(leader);
    meetings.insert(this);
};

Meeting::~Meeting()
{
    
    meetings.erase(this);
    
}

vector<string> Meeting::getParticipantList() const
{
    
    vector<string> names;
    
    for ( const Person* p : participants ) //auto& p er det samme, men det auto gjør er å finne ut at dette er en const Person*.
    {
        
        names.push_back((*p).getName());
        //names.push_back(p->getName()); En annen måte å skrive på, men det gjør akkurat det samme.
        
    }
    
    return names;
}

ostream& operator<<(ostream& output, const Meeting& meeting)
{
    
    output << "Leader: " << *(meeting.getLeader()) << endl;
    output << "Starttime: " << meeting.getstartTime() << endl;
    output << "Endtime: " << meeting.getendTime() << endl;
    output << "Subject: " << meeting.getSubject() << endl;
    output << "Location: " << getCampusString(meeting.getLocation()) << endl;
    output << "List of participants: " << endl;
    
    for (string person : meeting.getParticipantList() )
    {
        output << person << endl;
        
    }
    return output;
}

int main()
{
Car g{3};
    Car l{2};
    Car p{4};

Person gunnar("Gunnar", "[email protected]", &g);
    Person lars("Lars", "[email protected]", &l);
    Person pernille("Pernille", "[email protected]", &p);

Meeting meeting(1,10,12,Campus::Trondheim,"Mathematics 1", &gunnar);
    
    meeting.addParticipants(&lars);
    meeting.addParticipants(&pernille);
    
    
    cout << meeting;

Please edit your post. Put SEPARATE files in separate sets of code tags and INDICATE THE NAMES of those files.

Please ensure that you have all your include statements (they are all clearly missing at present) and that your copy-and-pasting hasn't lost bits (as at present).

We need to be able to COMPILE your code!

Include all .h and .cpp files. I sincerely hope that you haven't put all your function definitions in .h files!

Also please make sure that your indentation is consistent.
Last edited on
Sorry, I couldn't keep myself from playing with your code.
I admit it can be a very annoying thing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#include <iostream>
#include <set>
#include <string>
#include <vector>

// ---------------------------------------------------------------------------
//
//                            class Car
//
// ---------------------------------------------------------------------------
class Car {
public:
    explicit Car(int free_seats_arg);

    int getFreeSeats() const;
    bool hasFreeSeats() const;
    void reserveFreeSeat();

private:
    int free_seats;
};


Car::Car(int free_seats_arg)
    : free_seats { free_seats_arg }
{
}


int Car::getFreeSeats() const
{
    return free_seats;
}


bool Car::hasFreeSeats() const
{
    return free_seats != 0;
}


void Car::reserveFreeSeat()
{
    --free_seats;
}


// ---------------------------------------------------------------------------
//
//                            class Person
//
// ---------------------------------------------------------------------------
class Person {
public:
    Person(std::string name_arg, std::string email_arg, Car* bil = nullptr);
    std::string getName() const;
    std::string getEmail() const;
    void setEmail(std::string mailname);
    bool hasAvailableSeats() const;

private:
    std::string name;
    std::string email;
    Car* car;

// friends:
    friend std::ostream& operator<< (std::ostream& output, const Person& p);
};


Person::Person(std::string name_arg, std::string email_arg, Car* car)
    : name { name_arg },
      email { email_arg },
      car { car }
{
}


std::string Person::getName() const
{
    return name;
}


std::string Person::getEmail() const
{
    return email;
}


void Person::setEmail(std::string mailname)
{
    email = mailname;
}


bool Person::hasAvailableSeats() const
{
    return car->hasFreeSeats();
}


//Overlasting av output parameter. Ikke en friendfunksjon av klassen.
std::ostream& operator<< (std::ostream& output, const Person& p)
{
    std::string available { "Ingen ledige seter i bilen." };
    if ( p.hasAvailableSeats() ) {
        available = "Ledige seter i bilen.";
    }

    output << "Navn: " << p.name
           << "\nEmail: " << p.email
           << "\nBil: " << available << '\n';

    return output;
}


// ----------------------------------------------------------------------------
//
//                              class Campus
//
// ----------------------------------------------------------------------------
class Campus {
public:
    Campus() = default;
    explicit Campus(int index_arg);
    std::string getCampus() const;
    void setCampus(int index_arg);

private:
    static const std::vector<std::string> where;
    int index {};
};


const std::vector<std::string> Campus::where { "Trondheim", "Ålesund", "Gjøvik" };


Campus::Campus(int index_arg)
{
    index = 0 <= index_arg && index_arg < static_cast<int>(where.size())
            ? index_arg : 0;
}


std::string Campus::getCampus() const
{
    return where.at(index);
}


void Campus::setCampus(int index_arg)
{
    index = index_arg;
}


// ----------------------------------------------------------------------------
//
//                              class Meeting
//
// ----------------------------------------------------------------------------
class Meeting {
public:
    Meeting(int day_arg,
            int start_time_arg,
            int end_time_arg,
            int location_arg,
            std::string subject_arg,
            const Person* leader_arg);
    ~Meeting();

    int getDay() const;
    int getstartTime() const;
    int getendTime() const;
    std::string getLocation() const;
    std::string getSubject() const;
    const Person* getLeader() const;
    void addParticipants(const Person* p);
    std::vector<std::string> getParticipantList() const;
    std::vector<const Person*> findPotentialCoDriving();

private:
    int day;
    int start_time;
    int end_time;
    Campus location;
    std::string subject;
    const Person* leader;
    std::set<const Person*> participants;
    static std::set<const Meeting*> meetings;   // ???
};


std::set<const Meeting*> Meeting::meetings;


Meeting::Meeting(int day_arg,
                 int start_time_arg,
                 int end_time_arg,
                 int location_arg,
                 std::string subject_arg,
                 const Person* leader_arg)
    : day { day_arg },
      start_time { start_time_arg },
      end_time { end_time_arg  },
      subject { subject_arg },
      leader { leader_arg }
{
    location.setCampus(location_arg);
    std::cout << "Konstruktøren har blitt kjørt.\n";
    participants.insert(leader);
    meetings.insert(this);
}


Meeting::~Meeting()
{
    meetings.erase(this);
}


int Meeting::getDay() const
{
    return day;
}


int Meeting::getstartTime() const
{
    return start_time;
}


int Meeting::getendTime() const
{
    return end_time;
}


std::string Meeting::getLocation() const
{
    return location.getCampus();
}


std::string Meeting::getSubject() const
{
    return subject;
}


const Person* Meeting::getLeader() const
{
    return leader;
}


void Meeting::addParticipants(const Person* p)
{
    participants.insert(p);
}


std::vector<std::string> Meeting::getParticipantList() const
{
    std::vector<std::string> names;
    for ( const Person* p : participants )  {
        // auto& p er det samme, men det auto gjør er å finne ut at dette er
        // en const Person*.
        names.push_back(p->getName());
    }
    return names;
}


std::ostream& operator<< (std::ostream& output, const Meeting& meeting)
{
    output << "Leader: " << *(meeting.getLeader())
           << "\nStarttime: " << meeting.getstartTime()
           << "\nEndtime: " << meeting.getendTime()
           << "\nSubject: " << meeting.getSubject()
           << "\nLocation: " << meeting.getLocation()
           << "\nList of participants:\n";

    for (const auto& person : meeting.getParticipantList() ) {
        output << " - " << person << '\n';
    }
    return output;
}


int main()
{
    Car g{3};
    Car l{2};
    Car p{4};

    Person gunnar("Gunnar", "[email protected]", &g);
    Person lars("Lars", "[email protected]", &l);
    Person pernille("Pernille", "[email protected]", &p);

    Meeting meeting(1, 10, 12, 0, "Mathematics 1", &gunnar);

    meeting.addParticipants(&lars);
    meeting.addParticipants(&pernille);

    std::cout << meeting << '\n';
}


Output (sorry, but my W7 console stubbornly refuses to deal with non-English characters...):
Konstrukt├©ren har blitt kj├©rt.
Leader: Navn: Gunnar
Email: [email protected]
Bil: Ledige seter i bilen.

Starttime: 10
Endtime: 12
Subject: Mathematics 1
Location: Trondheim
List of participants:
 - Pernille
 - Lars
 - Gunnar

Topic archived. No new replies allowed.