Comparator 将 M×N 转化成 M+N
来源:互联网 发布:淘宝身份认证 编辑:程序博客网 时间:2024/05/16 05:41
用C++写程序经常需要写一些很小的functor,最常见的例子就是 compare functor,排序的,查找的,自己每定义一个数据结构,就要定义一个 compare functor,甚至多个(对不同字段)。甚至,针对指针的,智能指针的……的compare,这件工作很繁琐,很容易使人厌倦。
举个例子,同一个数据结构有M个字段,这些字段有P种类型,还有有N种不同的访问方式(直接提取、通过指针、通过智能指针、甚至通过反序列化等等),要实现所有这些情况的查找/排序,就需要 M×N 个 compare functor 的定义!
从 boost::multi_index 中学到一点,将 KeyExtractor 和 Comparator 分离,这样,只需要写 P 个Comparator,M+N个KeyExtractor,一般情况下,甚至不需要写Comparator,因为字段类型大多是内建类型,Comparator是默认的。举个例子吧:
using namespace std;
using boost::shared_ptr;
//using boost::intrusive_ptr;
struct mydata
{
int d1, d2, d3, d4, d5;
string s1, s2, s3;
};
struct mydata_get_int
{
int offset;
mydata_get_int(int offset) : offset(offset) {}
int operator()(const mydata& x) const
{
return *(int*)(offset + (unsigned char*)&x);
}
// 假定T 就是mydata* 或者智能指针
template<class T>
int operator()(const T& x) const
{
return *(int*)(offset + (unsigned char*)&(*x));
}
};
struct mydata_get_str
{
int offset;
mydata_get_str(int offset) : offset(offset) {}
const string& operator()(const mydata& x) const
{
return *(string*)(offset + (unsigned char*)&x);
}
// 假定T 就是mydata* 或者智能指针
template<class T>
const string& operator()(const T& x) const
{
return *(string*)(offset + (unsigned char*)&(*x));
}
};
class ExtractCompare
{
KeyExtractor m_extractor;
KeyCompare m_comp;
public:
ExtractCompare(const KeyExtractor& ext = KeyExtractor(),
const KeyCompare& comp = KeyCompare())
: m_extractor(ext), m_comp(comp) {}
template<class T1, class T2>
bool operator()(const T1& t1, const T2& t2) const
{
return m_comp(m_extractor(t1), m_extractor(t2));
}
};
int main(int argc, char* argv[])
{
vector<mydata> v1;
vector<mydata*> v2;
vector<shared_ptr<mydata> > v3;
//vector<intrusive_ptr<mydata> > v4;
// .... fill some data to v1, v2, v3
sort(v1.begin(), v1.end(), make_ec(mydata_get_int(FIELD_OFFSET(mydata, d1)), less<int>()));
sort(v2.begin(), v2.end(), make_ec(mydata_get_int(FIELD_OFFSET(mydata, d2)), less<int>()));
sort(v3.begin(), v3.end(), make_ec(mydata_get_str(FIELD_OFFSET(mydata, s3)), less<string>()));
return 0;
}
其中的ExtractCompare和make_ec可以作为公用代码,在多个程序中使用。
使用FIELD_OFFSET,在不降低效率的前提下,避免了代码膨胀。当然,这个例子中因为vector元素类型不同,会生成sort的3个不同版本,但是,如果不使用FIELD_OFFSET,而是直接再写一个extractor,这里会生成sort的4个版本。当然,一般情况下,不会像这样同时使用三个不同类型的vector。
C++0X 问世以后,其中的closure功能或许会使得这种方法显得过时,但是在没有closure的当前编译器上,这种方法还是很实用的。
- Comparator 将 M×N 转化成 M+N
- 使用Dev c++ 将m进制数n转化成一个十进制数
- 编写将一个十进制数M转化成N进制数(2≤N≤16)的程序.
- 给定一个十进制数M,以及需要转换的进制数N。 将十进制数M转化为N进制数
- 输出n-m-n
- 将一个N进制数转换成M进制数(源码)
- 将正整数N转换成m(2-16)进制数
- 每天一道LeetCode-----将m × n矩阵按照顺时针螺旋顺序转化成一维数组
- poj 1036 n!/(n-m)!*m!
- 输入n个数,将前n-m个数往后移动m位,最后m位数作为前m个数
- m选n算法
- M选N
- M*N的矩阵
- sigma(n^m)
- m的n次方
- 随机数产生 M-N
- C(m,n)
- poj2893 M × N Puzzle
- CronTab命令介绍
- 利用ListControl控件来绑定分层次的数据
- freebsd扫盲之mysql安装、启动、重启和设置
- Open Scene Graph
- Hibernate3 相关操作
- Comparator 将 M×N 转化成 M+N
- flex使用有感
- 为什么美女喜欢软件开发的gg做老公.
- VC++ 6.0 中如何使用 CRT 调试功能来检测内存泄漏
- 开启rewrite功能及检测示例
- Lucene基本知识
- flex入门1----环境搭建
- 对文件操作的一些方法
- 推荐46款免费软件