How to handle the 'C2678 binary '<' no operator found' error"

Hi Everyone,

I'm trying to figure out a way to solve the C2678 error in my code. I'm using a map, which stores an object as the key and a vector of objects as it's value. I found out, that I should either define the operator< or overload it, but I have no idea how it should be done.

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
#include"Student.h"
#include"Book.h"
#include<iostream>
#include<conio.h>
#include<string>
#include<vector>
#include<map>

using namespace std;

ostream& operator << (ostream& out, const map<Student, vector<Book> >& M) {

	int i = 1;

	for (auto key : M) {
		out << "Student: " << key.first << " : " << endl;
			for (auto val : key.second) {
				out << "Position "<< i << " : " << val << endl;
				i++;
			}
	}
	return out;
}


void insert_and_display() {
	
	string firstname, lastname, title, author;
	int student_id, book_id, pages;

	Student S;
	Book B;

	vector<Book> V;
	map<Student, vector<Book>> students_books;

	cout << "Enter student's name: "; cin >> firstname;
	cout << "Enter lastname: "; cin >> lastname;
	cout << "Enter ID: "; cin >> student_id;

	S.set_firstname(firstname);
	S.set_lastname(lastname);
	S.set_studentID(student_id);

	_getch();

	while (true)
	{
		cout << "Enter book title: "; getline(cin, title);
		cout << "Enter author"; getline(cin, author);
		cout << "Enter page number: "; cin >> pages;
		cout << "Enter book ID: "; cin >> book_id;

		cout << "\n";
		
		B.set_title(title);
		B.set_author(author);
		B.set_pages(pages);
		B.set_bookID(book_id);

		V.push_back(B);
		
		cout << "Loan another book? (Y/N) \n";

		char choice;

		if (choice == 'N' || choice == 'n')
		{
			students_books[S] = V;

			cout << students_books;
			cout << endl;
		
			break;
		}
	}
	exit(0);
}

int main() {

	insert_and_display();

	return 0;
}  
You can define the operator within your declaration of class Student:
1
2
3
4
5
6
class Student {
...
public:
    // return true if *this < rhs
    bool operator < (const Student &rhs) const;  // rhs is "right hand side" 
};


And the definition:
1
2
3
4
bool Student::operator < (const Student &rhs) const
{
    // write code that returns true if *this < rhs. Otherwise false.
}


So when is one student "less than" another? That's up to you.
Last edited on
I found out, that I should either define the operator< or overload it, but I have no idea how it should be done.

A map must be orderable (by the key). By default, this uses the less-than operator (or you can pass in your own custom function).

So if you want to use an std::map, you have to have some sort of ordering to your Student objects.

For example, you can compare by student ID. This is good enough assuming student IDs are unique. If they're not, you'd want to also compare by last name, first name or something like that.
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
#include <iostream>
#include <string>
#include <map>
#include <vector>
using std::string;
using std::vector;

struct Book {
	string title;
};

struct Student {
	int id;
	string first;
	string last;
};

bool operator<(const Student& a, const Student& b)
{
	return a.id < b.id;
}

int main()
{
	std::map<Student, vector<Book>> student_books;

	student_books.insert( std::pair<Student, vector<Book>>(
		{1234, "Jane", "Doe"},
		vector<Book>{ {"War and Peace"}, {"The Hobbit"} }
	));
	
	student_books.insert( std::pair<Student, vector<Book>>(
		{456, "John", "Smith"},
		vector<Book>{ {"Anna Karenina"} }
	));
	
	student_books.insert( std::pair<Student, vector<Book>>(
		{456, "Billy", "the Kid"},
		vector<Book>{ {"An Elementary Treatise on Electricity"}, {"Other books I haven't read"} }
	));
	
	for (const auto& element : student_books)
	{
		std::cout << element.first.id << "\n";
		for (const auto& book : element.second)
		{
			std::cout << "  " << book.title;
		}
		std::cout << '\n';
	}

}

(Notice in this example, Billy the Kid didn't get inserted because the id was the same as the previous student)
456
  Anna Karenina
1234
  War and Peace  The Hobbit
Last edited on
Topic archived. No new replies allowed.