Click here to Skip to main content
15,885,216 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
This simple code compiles and runs fine using VC++ 10:
C++
#include "stdafx.h"
#include <string>
#include <iostream>

using namespace std;

class Foo
{
public:
	Foo();
	Foo(int i, string s) { data = make_pair(i, s); };
	bool const operator==(const Foo& f) { return f.data == data; };
private:
	pair<int, string> data;
	int stuff;
};

int _tmain(int argc, _TCHAR* argv[])
{
	Foo f1(10, "xyz");
	Foo f2(10, "xyz");
	cout << ((f1 == f2) ? "equal" : "not equal") << endl;
	return 0;
}

However, if I change the Foo class so that the pair now consists of two of my classes:
C++
#include "stdafx.h"
#include <string>
#include <iostream>

using namespace std;

class Bar
{
public:
	Bar();
	Bar(string, string);
	bool const operator==(const Bar& b) { return b.s1 == s1 && b.s2 == s2; };
private:
	string s1;
	string s2;
	int k;
};

class Foo
{
public:
	Foo();
	Foo(Bar b1, Bar b2) { data = make_pair(b1, b2); };
	bool const operator==(const Foo& f) { return f.data == data ; };
private:
	pair<Bar, Bar> data;
	int stuff;
};

int _tmain(int argc, _TCHAR* argv[])
{
	Bar b1("abc", "xyz");
	Bar b2("abc", "xyz");
	Foo f1(b1, b2);
	Foo f2(b1, b2);
	cout << ((f1 == f2) ? "equal" : "not equal") << endl;
	return 0;
}

it will not compile and I get:
1>------ Build started: Project: pair_test, Configuration: Debug Win32 ------
1>  pair_test.cpp
1>c:\program files\microsoft visual studio 10.0\vc\include\utility(305): error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const Bar' (or there is no acceptable conversion)
1>          c:\program files\microsoft visual studio 10.0\vc\include\exception(470): could be 'bool std::operator ==(const std::_Exception_ptr &,const std::_Exception_ptr &)'
1>          c:\program files\microsoft visual studio 10.0\vc\include\exception(475): or       'bool std::operator ==(std::_Null_type,const std::_Exception_ptr &)'
1>          c:\program files\microsoft visual studio 10.0\vc\include\exception(481): or       'bool std::operator ==(const std::_Exception_ptr &,std::_Null_type)'
1>          c:\program files\microsoft visual studio 10.0\vc\include\system_error(408): or       'bool std::operator ==(const std::error_code &,const std::error_condition &)'
1>          c:\program files\microsoft visual studio 10.0\vc\include\system_error(416): or       'bool std::operator ==(const std::error_condition &,const std::error_code &)'
1>          c:\documents and settings\charles\my documents\visual studio 2010\projects\pair_test\pair_test.cpp(12): or       'const bool Bar::operator ==(const Bar &)'
1>          while trying to match the argument list '(const Bar, const Bar)'
1>          c:\documents and settings\charles\my documents\visual studio 2010\projects\pair_test\pair_test.cpp(24) : see reference to function template instantiation 'bool std::operator ==<Bar,Bar>(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' being compiled
1>          with
1>          [
1>              _Ty1=Bar,
1>              _Ty2=Bar
1>          ]
1>c:\program files\microsoft visual studio 10.0\vc\include\utility(305): error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const Bar' (or there is no acceptable conversion)
1>          c:\program files\microsoft visual studio 10.0\vc\include\exception(470): could be 'bool std::operator ==(const std::_Exception_ptr &,const std::_Exception_ptr &)'
1>          c:\program files\microsoft visual studio 10.0\vc\include\exception(475): or       'bool std::operator ==(std::_Null_type,const std::_Exception_ptr &)'
1>          c:\program files\microsoft visual studio 10.0\vc\include\exception(481): or       'bool std::operator ==(const std::_Exception_ptr &,std::_Null_type)'
1>          c:\program files\microsoft visual studio 10.0\vc\include\system_error(408): or       'bool std::operator ==(const std::error_code &,const std::error_condition &)'
1>          c:\program files\microsoft visual studio 10.0\vc\include\system_error(416): or       'bool std::operator ==(const std::error_condition &,const std::error_code &)'
1>          c:\documents and settings\charles\my documents\visual studio 2010\projects\pair_test\pair_test.cpp(12): or       'const bool Bar::operator ==(const Bar &)'
1>          while trying to match the argument list '(const Bar, const Bar)'

It looks like I'm missing something obvious here, but searching hasn't helped much. Do I have to explicitly define the == operator for pair<bar,>? The generic == operator should work fine if it knows how to compare Bar objects, I would think.
Posted

Your comparison operators are not defined const, but the Foo comparison operator provides const arguments. Therefore no match is found. Try this:
C++
class Bar
{
public:
    ...
    bool const operator==(const Bar& b) const { return b.s1 == s1 && b.s2 == s2;
    //  watch this added const here ......^
};
class Foo
{
public:
	...
	bool const operator==(const Foo& f) const { return f.data == data ; };

Note that the const after the return type is a qualifier to the return type, not to the function!
 
Share this answer
 
Comments
Joren Heit 10-Jun-14 10:20am    
On a sidenote, there's no point in having bool const as a return type. Or any return by const value for that matter.
Stefan_Lang 11-Jun-14 3:31am    
Indeed. I only left it there to keep the required change at a minimum. (and to put my final note into context)
fuzzy27 10-Jun-14 12:01pm    
I guess I tried all the combinations involving const except the right one (that's why const was still on the return types). In the end, only the Bar operator requires const.
Thanks to everyone who replied.
Stefan_Lang 11-Jun-14 3:23am    
Always remember that when you want to call a method on a const object, the method must be declared const as well. That is why you should always make sure to declare all methods const that do not modify an object.

P.S.: I do agree that the const syntax is messed up: sometimes it must be to the right (class methods), sometimes to the left (constant definitions), and sometimes it doesn't matter. A method that reliably works in C is reading a type definition from right to left. Unfortunately some elements in the C++ syntax make that difficult, and I'm not really sure you always end up with the right interpretation of a type in C++ ...
Joren Heit 11-Jun-14 16:59pm    
Funny you should say that! I always found that reading right to left clarifies matters in C++ as well. For example:
int const *ptr is a pointer to a constant integer, whereas int *const ptr is a constant pointer to an int. This is why I always tell people to write const to the right of the thing that's constant. So no const int *ptr, even though it's perfectly valid and seen a lot...
you compare the object of the pair template
C++
private:
    pair<Bar, Bar> data;


in
C#
bool const operator==(const Foo& f) { return f.data == data ; };


that makes no sense. You got to compare each member of that pair. Maybe that fits for you:
C#
bool const operator==(const Foo& f) { return (f.data.first == data.first) && (f.data.second == data.second) ; };
 
Share this answer
 
Comments
fuzzy27 10-Jun-14 2:31am    
Thanks for your prompt answer KarstenK.

In the two examples, the comparison is done in the same place. The difference is that in one case the pair consists of <int, string=""> and in the other the pair is <bar, bar="">. You are correct when you say that each member of the pair has to be compared. When the pair members are <int, string="">, std::pair::operator== for can compare them; I don't have to do anything extra. When the pair members are objects, std::pair::operator== should be able to compare them if I've defined (in this case) Bar::operator==. This operator is defined, but the code doesn't compile. The first error message says that Bar::operator== was not found, which means it was looking for it so pair::operator== could use it. But why is it not found?
Is the definition wrong? Is it in the wrong place?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900