Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > STL: container's values setup by another container

Reply
Thread Tools

STL: container's values setup by another container

 
 
Maitre Bart
Guest
Posts: n/a
 
      02-06-2004
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.


 
Reply With Quote
 
 
 
 
Andreas Müller
Guest
Posts: n/a
 
      02-06-2004

"Maitre Bart" <(E-Mail Removed)> schrieb im Newsbeitrag
news:c00514$doi$(E-Mail Removed)...
> 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


 
Reply With Quote
 
 
 
 
Maitre Bart
Guest
Posts: n/a
 
      02-11-2004

"Andreas Müller" <(E-Mail Removed)> wrote in message
news:c00906$10ercf$(E-Mail Removed)-berlin.de...
>
> "Maitre Bart" <(E-Mail Removed)> schrieb im Newsbeitrag
> news:c00514$doi$(E-Mail Removed)...
> > 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?


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
container within a container issue: set in the map puzzlecracker C++ 8 09-21-2008 11:08 PM
container inside container in stl wolverine C++ 2 07-24-2006 03:08 PM
Copy elements from one STL container to another STL container Marko.Cain.23@gmail.com C++ 4 02-16-2006 05:03 PM
std::transform container => std::abs(container) Steven T. Hatton C++ 4 12-05-2004 07:10 AM
std::container::iterator vs std::container::pointer Vivi Orunitia C++ 11 02-04-2004 08:09 AM



Advertisments