STL::find does unable to call overloaded operator==

P

Prakash Bande

Hi,
I have bool operator == (xx* obj, const string st). I have declared it
as friend of class xx. I am now able to do this:
xx ox;
string st;
if (&ox == st)
{
}
But, when I have a vector<xx*> and use stl find
string xyz;
vector<xx*>::iterator i = find(ii, xv.end(), xyz);

c:\program files\include\algorithm(43) : error C2679: binary '==' : no
operator defined which takes a right-hand operand of type 'const class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >' (or there is no acceptab
le conversion)

Here is a code snippet:

#include "stdafx.h"
#include <string>
#include <vector>
#include <iostream.h>
using namespace std;
class xx;
bool operator == (xx* obj, const string st);
#include <algorithm>

class xx
{
friend bool operator == (xx* obj, const string st);
private:
string ab;
int i;
public:
xx(string a);
};

xx::xx(string a)
{
ab = a;
}
bool operator == (xx* obj, const string st)
{
if (st == obj->ab)
return true;
return false;
}

int main(int argc, char* argv[])
{
printf("Hello World!\n");
vector<xx*> xv;
xx x1("some1");
xv.push_back(&x1);
xx x2("some2");
vector<xx*>::iterator ii = xv.begin();
string xyz = "some2";
if (*ii == xyz )
{
}
while (ii != xv.end())
{
vector<xx*>::iterator i = find(ii, xv.end(), xyz);
xx *f = *i;
ii = i;
ii++;
}
}
 
T

tom_usenet

Hi,
I have bool operator == (xx* obj, const string st). I have declared it
as friend of class xx. I am now able to do this:
xx ox;
string st;
if (&ox == st)
{
}
But, when I have a vector<xx*> and use stl find
string xyz;
vector<xx*>::iterator i = find(ii, xv.end(), xyz);

c:\program files\include\algorithm(43) : error C2679: binary '==' : no
operator defined which takes a right-hand operand of type 'const class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >' (or there is no acceptab
le conversion)

Here is a code snippet:

#include "stdafx.h"
#include <string>
#include <vector>
#include <iostream.h>

That should be
#include <iostream>
(many latest version compilers, including MSVC7.1 don't even have
<iostream.h>, and it is non-standard).


With that one change, it compiles and links fine (on VC7.1, for one).
I think your compiler doesn't implement argument dependent lookup, so
it doesn't find your globally declared operator, but instead only
finds the various operator==s declared in std. You may want to
upgrade.

Tom
 
Z

zvesko

Prakash Bande said:
Hi,
I have bool operator == (xx* obj, const string st). I have declared it
as friend of class xx. I am now able to do this:
xx ox;
string st;
if (&ox == st)
{
}
But, when I have a vector<xx*> and use stl find
string xyz;
vector<xx*>::iterator i = find(ii, xv.end(), xyz);

c:\program files\include\algorithm(43) : error C2679: binary '==' : no
operator defined which takes a right-hand operand of type 'const class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >' (or there is no acceptab
le conversion)

Here is a code snippet:

#include "stdafx.h"
#include <string>
#include <vector>
#include <iostream.h>
using namespace std;
class xx;
bool operator == (xx* obj, const string st);
#include <algorithm>

class xx
{
friend bool operator == (xx* obj, const string st);
private:
string ab;
int i;
public:
xx(string a);
};

xx::xx(string a)
{
ab = a;
}
bool operator == (xx* obj, const string st)
{
if (st == obj->ab)
return true;
return false;

type of (st == obj->ab) is bool so

return (st == obj->ab) ;

is enough
}

int main(int argc, char* argv[])
{
printf("Hello World!\n");
vector<xx*> xv;
xx x1("some1");
xv.push_back(&x1);
xx x2("some2");

I think you forgot to add

xv.push_back(&x2);
vector<xx*>::iterator ii = xv.begin();
string xyz = "some2";
if (*ii == xyz )
{
}
while (ii != xv.end())
{
vector<xx*>::iterator i = find(ii, xv.end(), xyz);
xx *f = *i;
ii = i;
ii++;
}
}

Very interesting, it compiles without a problem on VC7.1 but fails on VC6,
which I assume you're using.
No idea why, and it is not restricted to find. VC6 refuses to compile when
you have global operator ==
where the first argument is not a struct/class.

for example

bool operator == (int i, const string &){ return false; }

int ints[] = { 1, 2, 3, 4 };
size_t cnt = count(ints, ints+4, string("aaa"));

fails, whereas

bool operator == (const string &, int i){ return false; }

string strings[] = { "a", "b", "c", "d" };
size_t cnt = count(strings, strings+4, 5);

compiles

To go back to your problem... this works:

instead of operator== use binary predicate

struct xx_equal : public ::std::binary_function<xx*, ::std::string,
bool>
{
bool operator()(xx * obj, const ::std::string & st) const
{
/*1*/ return (st == obj->ab);

************
VC6 doesn't complain if you use your original operator == here
************
return obj == st;
}
};

then use find_if instead of find

#include <functional> // for bind2nd

vector<xx*>::iterator i = find_if(ii, xv.end(), bind2nd(xx_equal(),
xyz));

you can declare xx_equal a friend of xx or even better declare accessor
function in xx for ab like

// inside xx
const string & get_ab() const { return ab; }

and instead of /*1*/ use

return (st == obj->get_ab());


VZ
 
Z

zvesko

This seems to work ok too.

move your operator== inside std namespace

//forward declare operator ==
namespace std { bool operator == (xx* obj, const string st); }

// to declare operator == as a friend
friend bool std::eek:perator==(xx* obj, const string st);

// to define operator ==
namespace std
{
bool operator == (xx* obj, const string st){ return (st == obj->ab) ; }
}

VZ
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,175
Messages
2,570,942
Members
47,490
Latest member
Finplus

Latest Threads

Top