binary '==' no operator found which takes a left hand operand of type Book

when i run this code , i got this error:

binary '==' no operator found which takes a left hand operand of type Book

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
  # include <fstream>
# include <string>
# include <vector>
# include <algorithm>
# include <iostream>
# include <sstream>
# include <map>
# include <set>
# include "book.hpp"


using namespace std;

int main()
{
	ifstream ifs("bookinfo.txt");

	if (ifs.fail())
	{
		cerr << "Input file opening failed " << endl;
		return EXIT_FAILURE;
	}


	vector <Book> v;
	string sTemp;


	map <string, int> m;


	while (ifs)
	{
		Book b;

		getline(ifs, b.sTitle, ',');
		getline(ifs, b.sAuthorLast, ',');
		getline(ifs, b.sAuthorFirst, ',');
		getline(ifs, b.sISBN, ',');
		getline(ifs, sTemp, ',');

		istringstream iss(sTemp);
		iss >> b.dCost;

		getline(ifs, sTemp, ',');

		istringstream iss2(sTemp);
		iss2 >> b.uQuantity;

		m[b.sTitle]++;

		v.push_back(b);

	}


	
	vector <Book>::iterator p = find(v.begin(), v.end(), "C++ primer" );
	if (p != v.end())
	{
		cout << "could not find the book" << endl;
	}
	else
	{
		cout << "book found " << endl;
    }
	


	cout << "test" << endl;
	system("pause");


}
Last edited on
I'm assuming book is a custom class you created. In order to use the == you need to overload it to use your class. This is because the compiler does not know which attributes to compare inside the class. For example

1
2
3
4
5
class car
{
     int topSpeed;
     int price;
}


In main you create two cars but which one (or both) of the attributed to you compare to see if they are equal?

Hope this helps!
The find function tries to compare each book in vector v with the string "C++ primer". This will only work if you have overloaded the == operator to to work with these two types, something you probably don't want to do because it doesn't makes sense to say that a book is equal to a string.

If you want to find a book with the title "C++ primer" you could use find_if instead and provide your own comparison functor.

 
vector <Book>::iterator p = find_if(v.begin(), v.end(), [](const Book& b){return b.sTitle == "C++ primer";} );
Last edited on
how do i overload the == operator:

i tried this in my header file book.hpp: and im getting too many parameters for this operator function

#pragma once

#include <string>

class Book{

public:
std::string sTitle;
std::string sAuthorLast;
std::string sAuthorFirst;
std::string sISBN;
double dCost;
unsigned uQuantity;


public:


bool operator == (Book const& lhs, Book const& rhs)
{
return lhs.sTitle == rhs.sTitle;
}


};



bool operator == (Book const& lhs, Book const& rhs)
{
return lhs.sTitle == rhs.sTitle;
}

Instead of overloading compare the title attributes. Lets say you have two instances of book called book1 and book2 and each one has its own title. You can compare the titles without overloading by directly comparing the attributes like this:

1
2
3
4
if(book1.title == book2.title) //if its a pointer do (book1->title == book2->title)
{
     //Do something
}


This lets you skip out on the overloading but makes the code a little messy.
Last edited on
so what should i do if book1.title == book2.title

if(book1.title == book2.title) //if its a pointer do (book1->title == book2->title)
{
//Do something
}
This version compiles:
Book.h
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
#ifndef BOOK_HEADER
#define BOOK_HEADER

#include <string>

class Book{
public:
    std::string sTitle;
    std::string sAuthorLast;
    std::string sAuthorFirst;
    std::string sISBN;
    double dCost;
    unsigned uQuantity;
    bool operator==(const char* title) const
    {
        return sTitle == title;
    }
    friend bool operator == (Book const& lhs, Book const& rhs);
};

bool operator == (Book const& lhs, Book const& rhs)
{
    return lhs.sTitle == rhs.sTitle;
}

#endif // BOOK_HEADER 


main.cpp:
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
# include <algorithm>
# include <iostream>
# include <fstream>
# include <map>
# include <set>
# include <sstream>
# include <string>
# include <vector>
# include "book.h"

using namespace std;

void waitForEnter()
{
    std::cout << "\nPress ENTER to continue...\n";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

int main()
{
    ifstream ifs("bookinfo.txt");

    if (ifs.fail())
    {
        cerr << "Input file opening failed " << endl;
        return EXIT_FAILURE;
    }

    vector <Book> v;
    string sTemp;

    map <string, int> m;

    while (ifs)
    {
        Book b;

        getline(ifs, b.sTitle, ',');
        getline(ifs, b.sAuthorLast, ',');
        getline(ifs, b.sAuthorFirst, ',');
        getline(ifs, b.sISBN, ',');
        getline(ifs, sTemp, ',');

        istringstream iss(sTemp);
        iss >> b.dCost;

        getline(ifs, sTemp, ',');

        istringstream iss2(sTemp);
        iss2 >> b.uQuantity;

        m[b.sTitle]++;

        v.push_back(b);
    }

    vector <Book>::iterator p = find(v.begin(), v.end(), "C++ primer" );
    if (p != v.end())
    {
        cout << "could not find the book" << endl;
    }
    else
    {
        cout << "book found " << endl;
    }


    cout << "test" << endl;
    waitForEnter();
}


Note: ‘compiles’ doesn’t mean it’s correct. For example, this part of your code:
1
2
3
4
5
6
7
8
9
	vector <Book>::iterator p = find(v.begin(), v.end(), "C++ primer" );
	if (p != v.end())
	{
		cout << "could not find the book" << endl;
	}
	else
	{
		cout << "book found " << endl;
    }

says it has found the book when it hasn’t and vice versa.
I am just curious to why i have to define an overload like this:


bool operator==(const char* title) const
{
return sTitle == title;
}

};


when u have already defined this outside of the class:

bool operator == (Book const& lhs, Book const& rhs)
{
return lhs.sTitle == rhs.sTitle;
}


if i don't use the line: friend bool operator == (Book const& lhs, Book const& rhs);

will it be the same if i write this :




lass Book{
public:
std::string sTitle;
std::string sAuthorLast;
std::string sAuthorFirst;
std::string sISBN;
double dCost;
unsigned uQuantity;

bool operator == (Book const& lhs, Book const& rhs)
{
return lhs.sTitle == rhs.sTitle;
}

};



I am just curious to why i have to define an overload like this:
bool operator==(const char* title) const
{
return sTitle == title;
}

};
when u have already defined this outside of the class:
bool operator == (Book const& lhs, Book const& rhs)
{
return lhs.sTitle == rhs.sTitle;
}

May I ask you what’s bad in the “code” tags?

1)
why i have to define an overload like this:
bool operator==(const char* title) const

You are going to compare the property “sTitle”, of type std::string, with a string literal ("C++ primer"):
vector <Book>::iterator p = find(v.begin(), v.end(), "C++ primer" );
So I supposed you needed a function that accepts a string literal and compares it with “sTitle”.

2)
when u have already defined this outside of the class:

I copied and pasted your code from your second post and that function was already there. Anyway, it compares two ‘Book’(s), not a ‘Book’ and a string literal.

3)
if i don't use the line: friend bool operator == (Book const& lhs, Book const& rhs);
will it be the same if i write this :
lass Book{
. . .
bool operator == (Book const& lhs, Book const& rhs)
{
return lhs.sTitle == rhs.sTitle;
}

Well, it doesn’t compile :-)

You can choose if you want your overloaded operators to be methods of your class or external functions, according to how you want to use them. There’re a lot of details here:
http://en.cppreference.com/w/cpp/language/operators

If you don’t feel confident with operator overloading, you can easily find a lot of tutorials about it on internet, but this topic is far beyond my poor English.
i have defined

bool operator == (Book const& lhs, Book const& rhs)
{
return lhs.sTitle == rhs.sTitle;
}

inside the class Book and it is giving me the error too many parameters

but u are using friend bool operator == (Book const& lhs, Book const& rhs); which also takes on two parameters inside class Book and it works ?

also can i change const * char to string inside this function :

so:


bool operator==(const char* title) const
{
return sTitle == title;
}


becomes

bool operator==(string title) const
{
return sTitle == title;
}



i have defined
bool operator == (Book const& lhs, Book const& rhs)
{
return lhs.sTitle == rhs.sTitle;
}
inside the class Book and it is giving me the error too many parameters
but u are using friend bool operator == (Book const& lhs, Book const& rhs); which also takes on two parameters inside class Book and it works ?

Are “code” tags really so hard to use?
The two-parameters overloaded operator is not a member of “class Book”.
Brushing up on ‘friendship’ could be boring, but helpful:
http://en.cppreference.com/w/cpp/language/friend

also can i change const * char to string inside this function :
so:
bool operator==(const char* title) const
{
return sTitle == title;
}
becomes
bool operator==(string title) const
{
return sTitle == title;
}

It looks harmless, doesn’t it? Just try.
Topic archived. No new replies allowed.