C++中,以类成员函数指针作为参数对std::map中的元素进行迭代处理
在C++中使用Map会遇到迭代Map中元素的问题,使用for循环迭代元素,无形中增加了一层括号;使用函数指针调用类成员函数时,通常做法是,提供一个静态函数作为函数指针指向的函数,在静态函数中提供类指针对成员函数的调用。下面的代码通过foreach模板函数提供解决这两种问题的一个实例。
#pragma once
#include <map>
/*
托管Map的类,Map中存储着对象的指针
*/
template<typename S>
class XMRList
{
// 重定义Map的类型别名,迭代器的类型别名,易于阅读
public:
typedef std::map<long, S*> MyMAP;
typedef typename MyMAP::iterator MyIterator;
typedef typename MyMAP::const_iterator MyConstIterator;
// 构造函数
public:
XMRList() { }
~XMRList() {this->ReslaseList();}
public:
// 从Map中查询对象,查询失败时,返回空指针
S* Find(long id)
{
MyIterator it = this->m_Map.find(id);
if (it != this->m_Map.end())
{
return it->second;
}
return NULL;
}
// 从Map中查询对象,查询失败时,返回空指针
S* Find(long id) const
{
MyConstIterator it = this->m_Map.find(id);
if (it != this->m_Map.end())
{
return it->second;
}
return NULL;
}
// 取得Map的大小
UINT GetCount() const
{
return this->m_Map.size();
}
MyIterator Begin()
{
return this->m_Map.begin();
}
MyConstIterator Begin() const
{
return this->m_Map.begin();
}
MyIterator End()
{
return this->m_Map.end();
}
MyConstIterator End() const
{
return this->m_Map.end();
}
public:
// 遍历Map中的对象,并调用相关类成员函数(1个参数)进行处理
template<typename T, typename R>
void foreach(T& o, R (T::* f)(S*))
{
MyIterator begin = this->m_Map.begin();
MyIterator end = this->m_Map.end();
for (; begin != end; ++begin)
{
(o.*f)(begin->second);
}
}
// 遍历Map中的对象,并调用相关类成员函数(2个参数)进行处理
template<typename T, typename R, typename A>
void foreach(T& o, A arg, R (T::* f)(S*, A))
{
MyIterator begin = this->m_Map.begin();
MyIterator end = this->m_Map.end();
for (; begin != end; ++begin)
{
(o.*f)(begin->second, arg);
}
}
// 遍历Map中的对象,并调用相关类成员函数(3个参数)进行处理
template<typename T, typename R, typename A2, typename A3>
void foreach(T& o, A2 arg2, A3 arg3, R (T::* f)(S*, A2, A3))
{
MyIterator begin = this->m_Map.begin();
MyIterator end = this->m_Map.end();
for (; begin != end; ++begin)
{
(o.*f)(begin->second, arg2, arg3);
}
}
// 遍历Map中的对象,并调用相关类成员函数(4个参数)进行处理
template<typename T, typename R, typename A2, typename A3, typename A4>
void foreach(T& o, A2 arg2, A3 arg3, A4 arg4, R (T::* f)(S*, A2, A3, A4))
{
MyIterator begin = this->m_Map.begin();
MyIterator end = this->m_Map.end();
for (; begin != end; ++begin)
{
(o.*f)(begin->second, arg2, arg3, arg4);
}
}
public:
// 为减少对map的依赖,提供的遍历map的函数
// foreach处理不了模板函数的问题,所以提供该函数
bool GetNextItor(MyIterator& itor)
{
if (itor == this->m_Map.end())
{
itor = this->m_Map.begin();
return true;
}
++itor;
if (itor == this->m_Map.end())
{
return false;
}
return true;
}
// 为减少对map的依赖,提供的遍历map的函数
// foreach处理不了模板函数的问题,所以提供该函数
bool GetNextItor(MyConstIterator& itor) const
{
if (itor == this->m_Map.end())
{
itor = this->m_Map.begin();
return true;
}
++itor;
if (itor == this->m_Map.end())
{
return false;
}
return true;
}
private:
void ReslaseList() // 释放集合中的数据
{
for (MyIterator it = this->m_Map.begin(); it != this->m_Map.end(); ++it)
{
delete it->second;
it->second = NULL;
}
this->m_Map.clear();
}
public:
MyMAP m_Map; // 托管的集合
};
函数的调用:
class CStateBase
{
public:
long m_ID;
}
class MapTest
{
public:
XMRList<CStateBase> m_MapProxy;
public:
void OnForeach(CStateBase* pState)
{
TRACE("遍历Map元素,编号:%d\n", pState->m_ID);
// ......
}
void TestForEach()
{
this->m_MapProxy.foreach(*this, &MapTest::OnForeach);
}
};