overload template function "operator==(pair)"

I am going to overload a global template operator function from <utility>
1
2
3
4
5
6
7
8
template<class _Ty1,
	class _Ty2> inline
	bool operator==(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test for pair equality
	return (_Left.first == _Right.first && _Left.second == _Right.second);
	}


by
1
2
3
4
5
6
7
8

typedef std::pair<std::string, int> psi;
 
// Only compare on the first element
bool operator==(const psi& l, const psi& r) {
  std::cout << l.first << " : " << r.first << std::endl;
  return l.first == r.first;
}


When I use find() function from <algorithm>, my overloaded function (operator==) does not work. The <utility> function (operator==) still works.

I am using VS2008 professional compiler.

Is my overloading problem or compiler problem?

thanks in advance for any advice.


Ugh. Try putting your function in the std namespace.

EDIT: though a better solution is to create a strong type rather than a typedef.
Last edited on
Thanks jsmith. Both of your ways are working well.

1. putting function in the std namespace
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 namespace std{

	 typedef  pair<string, int> psi;


	//Only compare on the first element
	 
       bool operator==(const pair<string, int>& l, const pair<string, int>& r) {

		/*std::cout <<l.first << " : " << r.first;
		if(l.first == r.first)
			std::cout << ", True"<<std::endl;*/

		return l.first == r.first;
	}
}


2. creating a strong type rather than a typedef
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class psi: public std::pair<std::string ,int>
{
public:
	psi(std::string s,int i):std::pair<std::string,int>(s,i)
	{
	}
};

//Only compare on the first element

bool operator==(const psi& l, const psi& r) {

	/*std::cout <<l.first << " : " << r.first;
	if(l.first == r.first)
	std::cout << ", True"<<std::endl;*/

	return l.first == r.first;
}



However, I don't think only typedef causing the problem.
I tried to use full scope reference rather than typedef, but it's still not working. as below:
1
2
3
4
5
6
7
8
9
bool operator==(const std::pair<std::string,int>& l, const std::pair<std::string,int>& r) {

	/*std::cout <<l.first << " : " << r.first;
	if(l.first == r.first)
	std::cout << ", True"<<std::endl;*/

	return l.first == r.first;
}


jsmith, thanks again.
Yes, I agree that the "typedef" in itself is not the problem. The problem is template ADL
(google "koenig lookup" and read the Wikipedia article). That's why you have to put
the compare function in the std namespace.

But that's kind of icky, and typedefs used this way aren't great either, so that's why
I suggested the strong type. (But I would have it contain a std::pair rather than
inherit).
Hi jsmith,

Do you mean to use std::pair as a member of psi?
like
1
2
3
4
5
6
7
class psi
{
     std::pair<std::string,int> p;
public:

    /*some interfaces*/
};



If so, what is the advantage of composition rather than inherit?
Is this type strong than inherit?

because inherit is "is a" relationship. but the composition is complete a new type.
Is my understanding correct?

I have read ADL and get more sense about the function calls.

thank you very much!
Most of the types in the STL (pair included) are not set up for inheritance by virtue of the fact that they don't
have virtual destructors, meaning that one cannot delete an object of the derived type through a base class
pointer without causing potential memory leaks because the derived destructor will not run. To me,
inheritance implies that I want my program to hold pointers to (references to) the base for reasons of
polymorphism. But, this is dangerous for the reason I just gave.

I'm going to guess that in your program, you aren't going to upcast pointers to psi's to pointers to
std::pair<std::string, int>. Therefore I would go with containment.

I can also refer you to C++ Coding Standards by Sutter and Alexandrescu (ISBN 0-321-11358-6).
Item #34 is "Prefer composition to inheritance". If you don't have access to the book, here's an excerpt
from the Summary section:

"... Inheritance is the second-tightest coupling relationship in C++, second only to friendship. Tight coupling
is undesirable and should be avoided ... prefer composition to inheritance unless you know that the latter
truly benefits your design."

Great.

Thank you very much, jsmith
It is also working in explicit specialisation:
1
2
3
4
5
6
7
typedef  std::pair< std::string, int> psi;

template<>
bool std::operator==(const psi& l, const psi& r) {

	return l.first == r.first;
}

Topic archived. No new replies allowed.