STL: container's values setup by another container

Discussion in 'C++' started by Maitre Bart, Feb 6, 2004.

  1. Maitre Bart

    Maitre Bart Guest

    What I want to perform is calling a member function of container 1
    (CRunner), using as argument the value of a container 2 (CNames). The
    purpose is to transfer values from C2 into C1 using a specific C1 member
    function. Both containers contains the same number of elements (or at least,
    C1 is larger than C2).

    As suggested by S. Meyers (and others), I would like to use an STL algorithm
    instead of a custom loop. Let say I have the following:

    class CRunner{
    string m_name;
    int m_order;

    public:
    bool SetOrder(int a_order) {m_order = a_order; return true;}
    bool SetName(const string& a_name) {m_name = a_name; return true;}
    };

    vector<string> NameTable;
    vector<CRunner> RunnerTable;

    I created a template functor/function pair to be used in for_each():

    template<class R, class T>
    class mem_fun_iter_t : unary_function<T*, R>
    {
    public:
    explicit mem_fun_iter_t(R (T::*p)(const T::iterator::value_type&),
    vector<T>::iterator i) : pmf(p), iter(i) {}
    R operator()(T* p) const {return (p->*pmf)(*iter++);}
    private:
    R (T::*pmf)(const T::iterator::value_type&);
    vector<T>::iterator iter;
    };

    template<class R, class T>
    inline static mem_fun_iter_t<R, T> mem_fun_iter(R (T::*p)(const
    T::iterator::value_type&), vector<T>::iterator i)
    {
    return mem_fun_iter_t<R, T, vector<T> >(p, i);
    }

    (...unfortunetaly, I wasn't able to specify a generic parameter for
    'vector', without getting all other kinds of errors...)

    So that once both containers are initalized and filled, I can safely call:

    for_each(NameTable.begin(), NameTable.end(), mem_fun_iter(CRunner::SetName,
    RunnerTable.begin()));

    But my compiler always generate this error:

    [...] error C2784: 'mem_fun_iter_t<R,T> mem_fun_iter(R (T::*)(const
    generic-type-264 &),generic-type-265)': could not deduce template argument
    for '<Unknown>' from 'bool (RUNNER::*)(const string &)'

    Is it my compiler (MSVS6) or is it a real deduction problem (missing
    parameter)?
    Is it a problem of algorithm? Is there any way to do the same with another
    algorithm (such as transform(), etc.)?
    Is there any way to reuse mem_fun* (with a binder or not) instead of the
    above custom template functor/function pair?
    Is there a way to make the call "end-of-container"-proof by using
    back_inserter()?

    I ask the those questions because I tried all those combinations without
    success.
    The task look simple, but caused me frustrations over the past 3 days.

    As a second part, what would be the implications if rather than having
    'vector<string> NameTable' I had:

    vector<CNames> NameTable;

    with:

    class CNames
    {
    //...
    public:
    string GetName();
    //...
    };

    Thanks for helping.
     
    Maitre Bart, Feb 6, 2004
    #1
    1. Advertising

  2. Re: container's values setup by another container

    "Maitre Bart" <> schrieb im Newsbeitrag
    news:c00514$doi$...
    > What I want to perform is calling a member function of container 1
    > (CRunner), using as argument the value of a container 2 (CNames). The
    > purpose is to transfer values from C2 into C1 using a specific C1 member
    > function. Both containers contains the same number of elements (or at

    least,
    > C1 is larger than C2).
    >
    > As suggested by S. Meyers (and others), I would like to use an STL

    algorithm
    > instead of a custom loop.


    <snip/>


    IMHO it would be ok to use std::transform. You can either use it to collect
    the results of the function calls, or just ignore the results:

    #include <vector>
    #include <string>
    #include <algorithm>
    #include <functional>
    struct Xox
    {
    bool Foo(const std::string& s)
    {
    std::cout << "Foo( " + s + ")" << std::endl;
    return s.size()>3;
    }
    };
    // an iterator that just eats everything up
    template<class CONTAINER>
    struct dummy_insert_iterator
    {
    dummy_insert_iterator<CONTAINER>& operator++(){ return *this; }
    dummy_insert_iterator<CONTAINER> operator++(int){ return *this; }
    dummy_insert_iterator<CONTAINER>& operator*(){ return *this; }
    dummy_insert_iterator<CONTAINER>& operator=(
    typename CONTAINER::const_reference Val){return *this;}
    };
    template<class CONTAINER> inline
    dummy_insert_iterator<CONTAINER> black_hole_back_inserter(const
    CONTAINER&)
    {
    return dummy_insert_iterator<CONTAINER>();
    }
    int main()
    {
    std::vector<Xox> x;
    x.push_back(Xox());
    x.push_back(Xox());
    std::vector<std::string> s;
    s.push_back("tst1");
    s.push_back("t2");
    // ... variant 1: collect results
    std::vector<bool> res;
    std::transform(x.begin(), x.end(), s.begin(), std::back_inserter(res),
    std::mem_fun_ref(Xox::Foo)
    );
    // ... variant 2: don't care for results:
    std::transform(x.begin(), x.end(), s.begin(),
    black_hole_back_inserter(res),
    std::mem_fun_ref(Xox::Foo)
    );
    return 0;
    }

    HTH,
    Andy
     
    Andreas Müller, Feb 6, 2004
    #2
    1. Advertising

  3. Maitre Bart

    Maitre Bart Guest

    Re: container's values setup by another container

    "Andreas Müller" <> wrote in message
    news:c00906$10ercf$-berlin.de...
    >
    > "Maitre Bart" <> schrieb im Newsbeitrag
    > news:c00514$doi$...
    > > What I want to perform is calling a member function of container 1
    > > (CRunner), using as argument the value of a container 2 (CNames). The
    > > purpose is to transfer values from C2 into C1 using a specific C1 member
    > > function. Both containers contains the same number of elements (or at

    > least,
    > > C1 is larger than C2).
    > >
    > > As suggested by S. Meyers (and others), I would like to use an STL

    > algorithm
    > > instead of a custom loop.

    >
    > <snip/>
    >
    >
    > IMHO it would be ok to use std::transform. You can either use it to

    collect
    > the results of the function calls, or just ignore the results:
    >
    > #include <vector>
    > #include <string>
    > #include <algorithm>
    > #include <functional>
    > struct Xox
    > {
    > bool Foo(const std::string& s)
    > {
    > std::cout << "Foo( " + s + ")" << std::endl;
    > return s.size()>3;
    > }
    > };
    > // an iterator that just eats everything up
    > template<class CONTAINER>
    > struct dummy_insert_iterator
    > {
    > dummy_insert_iterator<CONTAINER>& operator++(){ return *this; }
    > dummy_insert_iterator<CONTAINER> operator++(int){ return *this; }
    > dummy_insert_iterator<CONTAINER>& operator*(){ return *this; }
    > dummy_insert_iterator<CONTAINER>& operator=(
    > typename CONTAINER::const_reference Val){return *this;}
    > };
    > template<class CONTAINER> inline
    > dummy_insert_iterator<CONTAINER> black_hole_back_inserter(const
    > CONTAINER&)
    > {
    > return dummy_insert_iterator<CONTAINER>();
    > }
    > int main()
    > {
    > std::vector<Xox> x;
    > x.push_back(Xox());
    > x.push_back(Xox());
    > std::vector<std::string> s;
    > s.push_back("tst1");
    > s.push_back("t2");
    > // ... variant 1: collect results
    > std::vector<bool> res;
    > std::transform(x.begin(), x.end(), s.begin(), std::back_inserter(res),
    > std::mem_fun_ref(Xox::Foo)


    In fact, "std::mem_fun1_ref" worked on my side.

    > );
    > // ... variant 2: don't care for results:
    > std::transform(x.begin(), x.end(), s.begin(),
    > black_hole_back_inserter(res),
    > std::mem_fun_ref(Xox::Foo)
    > );
    > return 0;
    > }
    >
    > HTH,
    > Andy
    >
    >


    Thanks for your precious help.

    BTW, did you get experienced by yourself with this stuf, or did you read a
    good book on putting in practice stl algorithms?
     
    Maitre Bart, Feb 11, 2004
    #3
    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. Allan Bruce

    To STL or not to STL

    Allan Bruce, Oct 16, 2003, in forum: C++
    Replies:
    41
    Views:
    1,070
    Christopher Benson-Manica
    Oct 17, 2003
  2. Replies:
    4
    Views:
    806
    Daniel T.
    Feb 16, 2006
  3. wolverine
    Replies:
    2
    Views:
    456
    Marcus Kwok
    Jul 24, 2006
  4. Chris Shenton
    Replies:
    1
    Views:
    1,455
    =?ISO-8859-1?Q?Michael_Str=F6der?=
    Aug 24, 2007
  5. Intransition

    [ANN] Ruby Setup 5 (setup.rb)

    Intransition, Jan 13, 2010, in forum: Ruby
    Replies:
    0
    Views:
    421
    Intransition
    Jan 13, 2010
Loading...

Share This Page