By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,655 Members | 962 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,655 IT Pros & Developers. It's quick & easy.

simply code with templete

P: n/a
mos
Hi!

There are two function almost the same:

function removelist()
{
for(list<a*>::iterator it = m_list.begin(); it != m_list.end(); )
{
a* p = *it;
if (!p->IsValid())
{
delete p;
it = m_list.erase(it)
}
else
++it;
}
}

function removemap()
{
for(map<int,a*>::iterator it = m_map.begin(); it != m_map.end(); )
{
a* p = it->second;
if (!p->IsValid())
{
delete p;
it = m_map.erase(it)
}
else
++it;
}
}

how can I use templete to simply the code like
template<class ...>
function removeT(...)
{
...
}

the problem is the list: p = *it and map: p = it->second

then
function removelist()
{
removeT(m_list)
}

function removemap()
{
removeT(m_map)
}


Jul 3 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
mos <mm*******@163.comwrote:
Hi!

There are two function almost the same:

function removelist()
{
for(list<a*>::iterator it = m_list.begin(); it != m_list.end(); )
{
a* p = *it;
if (!p->IsValid())
{
delete p;
it = m_list.erase(it)
}
else
++it;
}
}

function removemap()
{
for(map<int,a*>::iterator it = m_map.begin(); it != m_map.end(); )
{
a* p = it->second;
if (!p->IsValid())
{
delete p;
it = m_map.erase(it)
}
else
++it;
}
}

how can I use templete to simply the code like
template<class ...>
function removeT(...)
{
...
}

the problem is the list: p = *it and map: p = it->second
Use an accessor. So in essence, you call a function, pass it the
iterator and it returns the value you want.

regards
--
jb

(reply address in rot13, unscramble first)
Jul 3 '06 #2

P: n/a
mos
Hi!
>
>the problem is the list: p = *it and map: p = it->second

Use an accessor. So in essence, you call a function, pass it the
iterator and it returns the value you want.
Thanks for your advise, I try like this:

class a
{
public:
bool IsValid(){
return false;
}
};

list<a*m_list;
map<int,a*m_map;

template<class T>
class wrap
{
public:
typedef typename T* Output;
typedef typename list<Output>::iterator Input1;
typedef typename map<int,Output>::iterator Input2;
Output m_p;
wrap(Input1 in1){
m_p = *in1;
}
wrap(Input2 in2){
m_p = in2->second;
}
Output operator() (){
return m_p;
}
};

template<class LIST, class T>
void removeT(LIST& m_list)
{
for(LIST::iterator it = m_list.begin(); it != m_list.end(); )
{
T* p = wrap<T>(it)();
if (!p->IsValid())
{
delete p;
it = m_list.erase(it);
}
else
++it;
}
}

void test()
{
removeT<list<a*>,a>(m_list);
removeT<map<int,a*>,a>(m_map);
}

it is work, am I right, or any better suggestion?
Best Regard.
mos.
Jul 3 '06 #3

P: n/a
mos <mm*******@163.comwrote:
Hi!
>>
>>the problem is the list: p = *it and map: p = it->second

Use an accessor. So in essence, you call a function, pass it the
iterator and it returns the value you want.

Thanks for your advise, I try like this:

class a
{
public:
bool IsValid(){
return false;
}
};

list<a*m_list;
map<int,a*m_map;

template<class T>
class wrap
{
public:
typedef typename T* Output;
typedef typename list<Output>::iterator Input1;
typedef typename map<int,Output>::iterator Input2;
Output m_p;
wrap(Input1 in1){
m_p = *in1;
}
wrap(Input2 in2){
m_p = in2->second;
}
Output operator() (){
return m_p;
}
};

template<class LIST, class T>
void removeT(LIST& m_list)
{
for(LIST::iterator it = m_list.begin(); it != m_list.end(); )
{
T* p = wrap<T>(it)();
if (!p->IsValid())
{
delete p;
it = m_list.erase(it);
}
else
++it;
}
}

void test()
{
removeT<list<a*>,a>(m_list);
removeT<map<int,a*>,a>(m_map);
}

it is work, am I right, or any better suggestion?
I haven't tried it, but it looks alright. As for a better
suggestion: you are limiting yourself to the list and map containers. If
you later decide to use a vector instead of a list, you will have to
manually change your wrap function. Here is what I came up with:
// general implementation for containers
template <typename C>
struct value_of
{
inline static typename C::value_type get (typename C::iterator i)
{
return *i;
}
};

// specialized implementation for maps
template <typename K, typename V>
struct value_of < typename std::map <K, V
{
inline static typename std::map <K, V>::value_type::second_type get
(typename std::map <K, V>::iterator i)
{
return i->second;
}
};

template <class C>
void remove (C& container)
{
for (typename C::iterator it = container.begin (); it !=
container.end(); )
{
if (!value_of <C>::get (it)->IsValid ())
{
delete value_of <C>::get (it);
it = container.erase (it);
}
else
{
++ it;
}
}
}

Also note that you no longer have to call your function like
"removeT <list <a*>, a(m_list);". Simply writing "remove (m_list);" is
sufficient (now the compiler will plug in all the necessary details for
you).

regards
--
jb

(reply address in rot13, unscramble first)
Jul 3 '06 #4

P: n/a
mos
Hi!

It is exactly I want!
and I learned a lot, thanks a lot.

Best regard.
mos.
Jul 3 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.