simply code with templete

M

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)
}
 
J

Jakob Bieling

mos said:
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
 
M

mos

Hi!
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.
 
J

Jakob Bieling

mos said:
Hi!

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top