using std::find_if() with a std::map

A

Anonymous

I have map variable that maps ids (unsigned int) to objects. Each object
has a Name() method.

I want to use std::find_if to fetch the object that name matches.

I defined my predicate like this:


class NameMatch
{
public:
inline NameMatch ( const std::string& name ) : m_name ( name )
{}

inline bool operator() ( const char* systemname ) const
{
return !stricmp(m_name.c_str(), systemname) ;
}

inline ~NameMatch(){}

private:
std::string m_name ;
};




I got the ff error:

error C2664: 'bool `anonymous-namespace'::NameMatch::eek:perator ()(const
char *) const' : cannot convert parameter 1 from 'std::pair<_Ty1,_Ty2>'
to 'const char *'

How may I implement this ?
 
G

Guest

I have map variable that maps ids (unsigned int) to objects. Each object
has a Name() method.

I want to use std::find_if to fetch the object that name matches.

I defined my predicate like this:


class NameMatch
{
public:
inline NameMatch ( const std::string& name ) : m_name ( name )
{}

inline bool operator() ( const char* systemname ) const
{
return !stricmp(m_name.c_str(), systemname) ;
}

inline ~NameMatch(){}

private:
std::string m_name ;
};




I got the ff error:

error C2664: 'bool `anonymous-namespace'::NameMatch::eek:perator ()(const
char *) const' : cannot convert parameter 1 from 'std::pair<_Ty1,_Ty2>'
to 'const char *'

find_if() will call your comparison method with the objects stored in
How may I implement this ?

class NameMatch
{
std::string m_name;

public:
NameMatch(std::string& name) : m_name(name) {}
bool operator()(const std::pair<unsigned int, object>& o)
{
return (m_name == o.Name());
}
};
 
A

Alf P. Steinbach

* Anonymous:
I have map variable that maps ids (unsigned int) to objects. Each object
has a Name() method.

I want to use std::find_if to fetch the object that name matches.

I defined my predicate like this:


class NameMatch
{
public:
inline NameMatch ( const std::string& name ) : m_name ( name )
{}

I'm not sure whether it's valid to add 'inline' to a function defined
(not just declared) in the class, but anyway it's superfluous: the
function is already inline by virtue of being defined here.

inline bool operator() ( const char* systemname ) const
{
return !stricmp(m_name.c_str(), systemname) ;
}

This operator returns true if the names are different.

It should return true if the names are equal.

Also, unless your objects convert implicitly to 'const char*' (which is
generally a bad idea), the argument should be a 'std::pair<int, O
const>' where O is your object type.

inline ~NameMatch(){}

private:
std::string m_name ;
};




I got the ff error:

error C2664: 'bool `anonymous-namespace'::NameMatch::eek:perator ()(const
char *) const' : cannot convert parameter 1 from 'std::pair<_Ty1,_Ty2>'
to 'const char *'

That's not from the code above, it's from you find_if call. And it
tells you that your operator's argument type is wrong, and what it
should be.

How may I implement this ?

See above.


Cheers, & hth.,

- Alf
 
A

Alf P. Steinbach

* Alf P. Steinbach:
* Anonymous:

I'm not sure whether it's valid to add 'inline' to a function defined
(not just declared) in the class, but anyway it's superfluous: the
function is already inline by virtue of being defined here.



This operator returns true if the names are different.

It should return true if the names are equal.

Uh sorry (late evening/early night this), it would work OK if the
function signature was OK, namely:
 
J

James Kanze

[On using find_if on a map...]
class NameMatch
{
std::string m_name;

public:
NameMatch(std::string& name) : m_name(name) {}
bool operator()(const std::pair<unsigned int, object>& o)

I seem to see this a lot, but... wouldn't it be preferable to
use Map::value_type rather than std::pair<...>? They mean the
same thing to the compiler, but not to whoever is reading the
program.
 
J

James Kanze

* Anonymous:
I'm not sure whether it's valid to add 'inline' to a function defined
(not just declared) in the class, but anyway it's superfluous: the
function is already inline by virtue of being defined here.

It's valid, but I agree that it's just noise.
This operator returns true if the names are different.

How do you know? I'd have to see the specifications of stricmp
first. It's not a standard function, so I can't look it up in
the standard, but if it follows the conventions of strcmp, then
it returns 0 when the strings are equal. And !0 is true, !
anything else false, so his function works. It's not readable,
of course, and won't pass code review in any place I've ever
worked in, but if the function follows the strcmp convention, he
really should compare the results with 0. But technically, it
works (although I had to think it through carefully to realize
this---the code is obfuscated).

(Of course, according to the C standard, function names
beginning with str are reserved for future expansion, so he's
probably treading very close to undefined behavior using this
function name himself. But I'm not sure that C++ has the same
restriction.)
It should return true if the names are equal.
Also, unless your objects convert implicitly to 'const char*'
(which is generally a bad idea), the argument should be a
'std::pair<int, O const>' where O is your object type.

That's really his problem. std::pair (and thus,
Map::value_type) doesn't convert implicitly to char const*.
Ever. And he can't change it. To use find_if on a map, the
operator() must take an argument which can be initialized with
an MapType::value_type (which is guaranteed to be std::pair<
key_type const, mapped_type >, but using std::pair instead of
MapType::value_type is another frequent obfuscation.)
 
G

Guest

[On using find_if on a map...]
class NameMatch
{
std::string m_name;

public:
NameMatch(std::string& name) : m_name(name) {}
bool operator()(const std::pair<unsigned int, object>& o)

I seem to see this a lot, but... wouldn't it be preferable to
use Map::value_type rather than std::pair<...>? They mean the
same thing to the compiler, but not to whoever is reading the
program.

Yes, except that it is more to type if you do not have a typedef for the
map. :)
 
J

James Kanze

On 2007-10-26 10:32, James Kanze wrote: [...]
I seem to see this a lot, but... wouldn't it be preferable to
use Map::value_type rather than std::pair<...>? They mean the
same thing to the compiler, but not to whoever is reading the
program.
Yes, except that it is more to type if you do not have a
typedef for the map. :)

But if you're worried about typing (or even only line length),
you do have the typedef, because otherwise, declaring an
iterator (e.g. to capture the results of find()) is also too
much to type:).

By using value_type, you have a lot less to change when the key
is changed to unsigned long. And you're sure that you've got
the type right. (Note that Alf put the const on the wrong
element. And Alf's hardly a beginner. It's easy to make such
small errors.)
 
R

Rajesh S R

find_if() will call your comparison method with the objects stored in


class NameMatch
{
std::string m_name;

public:
NameMatch(std::string& name) : m_name(name) {}
bool operator()(const std::pair<unsigned int, object>& o)
{
return (m_name == o.Name());

Is it not return (m_name == o.second.Name()); ?
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top