STL: container's values setup by another container | | |
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. | | | | re: STL: container's values setup by another container
"Maitre Bart" <lemieux@cae.com> schrieb im Newsbeitrag
news:c00514$doi$1@dns3.cae.ca...[color=blue]
> 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[/color]
least,[color=blue]
> C1 is larger than C2).
>
> As suggested by S. Meyers (and others), I would like to use an STL[/color]
algorithm[color=blue]
> instead of a custom loop.[/color]
<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 | | | | re: STL: container's values setup by another container
"Andreas Müller" <me@privacy.net> wrote in message
news:c00906$10ercf$1@ID-83644.news.uni-berlin.de...[color=blue]
>
> "Maitre Bart" <lemieux@cae.com> schrieb im Newsbeitrag
> news:c00514$doi$1@dns3.cae.ca...[color=green]
> > 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[/color]
> least,[color=green]
> > C1 is larger than C2).
> >
> > As suggested by S. Meyers (and others), I would like to use an STL[/color]
> algorithm[color=green]
> > instead of a custom loop.[/color]
>
> <snip/>
>
>
> IMHO it would be ok to use std::transform. You can either use it to[/color]
collect[color=blue]
> 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)[/color]
In fact, "std::mem_fun1_ref" worked on my side.
[color=blue]
> );
> // ... 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
>
>[/color]
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? |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,471 network members.
|