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

Discussion in 'C++' started by Anonymous, Oct 25, 2007.

  1. Anonymous

    Anonymous 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 *'

    How may I implement this ?
     
    Anonymous, Oct 25, 2007
    #1
    1. Advertising

  2. On 2007-10-25 23:53, Anonymous wrote:
    > 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
    the map, which (in your case) is an std::pair<unsigned int, object>
    where object is whatever kinds of objects you store.

    > 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());
    }
    };

    --
    Erik Wikström
     
    =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=, Oct 25, 2007
    #2
    1. Advertising

  3. * 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: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Oct 25, 2007
    #3
  4. * 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.


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


    > 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: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Oct 25, 2007
    #4
  5. Anonymous

    James Kanze Guest

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

    On Oct 26, 12:19 am, Erik Wikström <> wrote:

    [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.

    > {
    > return (m_name == o.Name());
    > }
    > };


    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Oct 26, 2007
    #5
  6. Anonymous

    James Kanze Guest

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

    On Oct 26, 12:33 am, "Alf P. Steinbach" <> wrote:
    > * 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.


    It's valid, but I agree that it's just noise.

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


    > 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.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Oct 26, 2007
    #6
  7. Re: using std::find_if() with a std::map

    On 2007-10-26 10:32, James Kanze wrote:
    > On Oct 26, 12:19 am, Erik Wikström <> wrote:
    >
    > [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. :)

    --
    Erik Wikström
     
    =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=, Oct 26, 2007
    #7
  8. Anonymous

    James Kanze Guest

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

    On Oct 26, 10:52 am, Erik Wikström <> wrote:
    > On 2007-10-26 10:32, James Kanze wrote:

    [...]
    > >> 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. :)


    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.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Oct 26, 2007
    #8
  9. Anonymous

    Rajesh S R Guest

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

    On Oct 26, 3:19 am, Erik Wikström <> wrote:
    > On 2007-10-25 23:53, Anonymous wrote:
    >
    >
    >
    > > 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
    > the map, which (in your case) is an std::pair<unsigned int, object>
    > where object is whatever kinds of objects you store.
    >
    > > 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());


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

    > }
    >
    > };
     
    Rajesh S R, Oct 26, 2007
    #9
  10. Re: using std::find_if() with a std::map

    On 2007-10-26 20:54, Rajesh S R wrote:
    > On Oct 26, 3:19 am, Erik Wikström <> wrote:
    >> On 2007-10-25 23:53, Anonymous wrote:
    >>
    >>
    >>
    >> > 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
    >> the map, which (in your case) is an std::pair<unsigned int, object>
    >> where object is whatever kinds of objects you store.
    >>
    >> > 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());

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


    Yes, sorry about that.

    --
    Erik Wikström
     
    =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=, Oct 26, 2007
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. marco_segurini
    Replies:
    3
    Views:
    2,286
    Karl Heinz Buchegger
    Jul 7, 2004
  2. ma740988
    Replies:
    18
    Views:
    1,026
    Daniel T.
    Jan 30, 2006
  3. Pierre Couderc

    How to find_if in a map?

    Pierre Couderc, Aug 9, 2006, in forum: C++
    Replies:
    4
    Views:
    393
    Jerry Coffin
    Aug 9, 2006
  4. Misiu
    Replies:
    3
    Views:
    2,387
    Misiu
    Jan 31, 2007
  5. Mike Copeland

    STL map find_if

    Mike Copeland, Jun 17, 2009, in forum: C++
    Replies:
    5
    Views:
    1,708
    Mike Copeland
    Jun 18, 2009
Loading...

Share This Page