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

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Anonymous

    #1

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

    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'::Nam eMatch::operato r ()(const
    char *) const' : cannot convert parameter 1 from 'std::pair<_Ty1 ,_Ty2>'
    to 'const char *'

    How may I implement this ?
  • =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=

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

    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'::Nam eMatch::operato r ()(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<unsig ned 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()(cons t std::pair<unsig ned int, object>& o)
    {
    return (m_name == o.Name());
    }
    };

    --
    Erik Wikström

    Comment

    • James Kanze

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

      On Oct 26, 12:19 am, Erik Wikström <Erik-wikst...@telia. comwrote:

      [On using find_if on a map...]
      class NameMatch
      {
      std::string m_name;
      >
      public:
      NameMatch(std:: string& name) : m_name(name) {}
      bool operator()(cons t std::pair<unsig ned 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:james.kan ze@gmail.com
      Conseils en informatique orientée objet/
      Beratung in objektorientier ter Datenverarbeitu ng
      9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

      Comment

      • James Kanze

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

        On Oct 26, 12:33 am, "Alf P. Steinbach" <al...@start.no 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:james.kan ze@gmail.com
        Conseils en informatique orientée objet/
        Beratung in objektorientier ter Datenverarbeitu ng
        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

        Comment

        • =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=

          #5
          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 <Erik-wikst...@telia. comwrote:
          >
          [On using find_if on a map...]
          >
          >class NameMatch
          >{
          > std::string m_name;
          >>
          >public:
          > NameMatch(std:: string& name) : m_name(name) {}
          > bool operator()(cons t std::pair<unsig ned 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

          Comment

          • James Kanze

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

            On Oct 26, 10:52 am, Erik Wikström <Erik-wikst...@telia. comwrote:
            On 2007-10-26 10:32, James Kanze wrote:
            [...]
            bool operator()(cons t std::pair<unsig ned 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:james.kan ze@gmail.com
            Conseils en informatique orientée objet/
            Beratung in objektorientier ter Datenverarbeitu ng
            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

            Comment

            • Rajesh S R

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

              On Oct 26, 3:19 am, Erik Wikström <Erik-wikst...@telia. comwrote:
              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'::Nam eMatch::operato r ()(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<unsig ned 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()(cons t std::pair<unsig ned int, object>& o)
              {
              return (m_name == o.Name());
              Is it not return (m_name == o.second.Name() ); ?
              }
              >
              };

              Comment

              • =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=

                #8
                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 <Erik-wikst...@telia. comwrote:
                >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'::Nam eMatch::operato r ()(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<unsig ned 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()(cons t std::pair<unsig ned int, object>& o)
                > {
                > return (m_name == o.Name());
                >
                Is it not return (m_name == o.second.Name() ); ?
                Yes, sorry about that.

                --
                Erik Wikström

                Comment

                Working...