functors and stl find_if

Discussion in 'C++' started by Michael, Feb 19, 2005.

  1. Michael

    Michael Guest

    Hi,
    I'm having a few problems getting the following find_if to work

    class Entity
    {

    };

    class factory
    {
    public:
    string GetType();
    Entity* CreateEntity();

    };

    class TheFactories
    {
    vector<factory*> factories;
    public:
    Entity* CreateEntity( const string& type)
    {
    vector<factory*>::iterator fact= find_if(

    factories.begin(),

    factories.end(),
    /* What goes
    here! */
    );
    if( fact != vector<factory*> ) return
    (*fact)->CreateEntity();
    assert(0);

    }

    };

    now I know I could unroll the find_if but I'm trying to get the hang of
    function objects and the like.

    If i have vector<string>, i can use equal_to<string>() but I don't
    understand where the arguements are supposed to go.
    I'd have thought the syntax would be:
    equal_to<string>(str1,str2)
    not bind1st( equal_to<string>(), str2 )!

    Ahhhhhh!

    Thanks Mike
     
    Michael, Feb 19, 2005
    #1
    1. Advertising

  2. Michael

    Matthias Guest

    Michael wrote:
    > /* What goes
    > here! */


    A functor or a function returning bool! Not a conditional statement.

    > If i have vector<string>, i can use equal_to<string>() but I don't
    > understand where the arguements are supposed to go.


    You have to use an adaptor like bind2nd:

    std::vector<string> coll;
    std::string string_which_equals_hello = find_if( coll.begin(),
    coll.end(), std::bind2nd( std::equal_to<string>(), "hello" ) );

    --
    Regards,
    Matthias
     
    Matthias, Feb 19, 2005
    #2
    1. Advertising

  3. Michael

    Matthias Guest

    Matthias wrote:
    > Michael wrote:
    >
    >> /*
    >> What goes
    >> here! */

    >
    >
    > A functor or a function returning bool! Not a conditional statement.
    >
    >> If i have vector<string>, i can use equal_to<string>() but I don't
    >> understand where the arguements are supposed to go.

    >
    >
    > You have to use an adaptor like bind2nd:
    >
    > std::vector<string> coll;
    > std::string string_which_equals_hello = find_if( coll.begin(),
    > coll.end(), std::bind2nd( std::equal_to<string>(), "hello" ) );
    >


    Of course find_if returns an iterator, not a string :)
    Correct that to:

    vector<string>::iterator pos = find_if(...);

    Sorry.


    --
    Regards,
    Matthias
     
    Matthias, Feb 19, 2005
    #3
  4. Michael

    SnaiL Guest

    Michael wrote:
    > Hi,
    > I'm having a few problems getting the following find_if to work
    >
    > class Entity
    > {
    >
    > };
    >
    > class factory
    > {
    > public:
    > string GetType();
    > Entity* CreateEntity();
    >
    > };
    >
    > class TheFactories
    > {
    > vector<factory*> factories;
    > public:
    > Entity* CreateEntity( const string& type)
    > {
    > vector<factory*>::iterator fact= find_if(


    Use const_iterator instead of iterator.

    >
    > factories.begin(),
    >
    > factories.end(),
    > /*

    What goes
    > here! */


    What goes here? Prefferable a function object.
    To find factory you wanna find, only one way is to write a simple
    functor to compare values, for example (it is not a best example, but
    many compilers should support it):

    template <typename PType, typename ArgType>
    class is_needed_factory : unary_function<PType, bool>
    { public:
    is_needed_factory(const ArgType & arg) : _name(arg) { }
    ~is_needed_factory() { }

    bool operator()(const PType p) const
    {
    return _name == p->GetType();
    }

    private:
    ArgType _name;
    };

    So, you will write something like this:

    vector<factory*>::const_iterator fact =
    find_if(factories.begin(), factories.end(),
    is_needed_factory<factory*, string>(type));


    > );
    > if( fact != vector<factory*> ) return
    > (*fact)->CreateEntity();


    Oops, fact is not a pointer to the vector of factory* pointers, fact is
    pointer to the factory object, this compare statement is invalid.
    Moreone, what value will be retuned if else?

    Some better code:

    if (fact != factories.end()) return (*fact)->CreateEntity();
    else return 0;


    > assert(0);
    >
    > }
    >
    > };
    >
    > now I know I could unroll the find_if but I'm trying to get the hang

    of
    > function objects and the like.
    >
    > If i have vector<string>, i can use equal_to<string>() but I don't
    > understand where the arguements are supposed to go.
    > I'd have thought the syntax would be:
    > equal_to<string>(str1,str2)
    > not bind1st( equal_to<string>(), str2 )!
    >
    > Ahhhhhh!
    >
    > Thanks Mike
     
    SnaiL, Feb 19, 2005
    #4
  5. Michael

    SnaiL Guest

    #include <vector>
    #include <string>
    #include <functional>
    #include <algorithm>

    using namespace std;

    class Entity
    {
    };

    class factory
    {
    public:
    string GetType() const;
    Entity* CreateEntity();

    };

    template <typename PType, typename ArgType>
    class is_needed_factory : unary_function<PType, bool>
    { public:
    is_needed_factory(const ArgType & arg) : _name(arg) { }
    ~is_needed_factory() { }

    bool operator()(const PType p) const
    {
    return _name == p->GetType();
    }

    private:
    ArgType _name;
    };

    class TheFactories
    {
    vector<factory*> factories;

    public:
    Entity* CreateEntity(const string & type)
    {
    vector<factory*>::const_iterator fact =
    find_if(factories.begin(), factories.end(),
    is_needed_factory<factory*, string>(type));

    if (fact != factories.end()) return (*fact)->CreateEntity();
    else return 0;
    }
    };
     
    SnaiL, Feb 19, 2005
    #5
    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,313
    Karl Heinz Buchegger
    Jul 7, 2004
  2. Gilles Rochefort
    Replies:
    6
    Views:
    369
    Pete Becker
    Jan 7, 2006
  3. Misiu
    Replies:
    3
    Views:
    2,451
    Misiu
    Jan 31, 2007
  4. Replies:
    1
    Views:
    509
  5. Mike Copeland

    STL map find_if

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

Share This Page