如何在模板中引用参数类中的一个特定member
C++模板有很多特性需要我们去挖掘,很多新的设计模式也都与模板使用相关,我们知道模板的一个基本特性就是可以根据传入的类型产生新的类型。围绕这个特性,可以衍生出很多的其它特性,比如自动为不同的类生成static变量,为不同的类型生成不同的行为等等。
这篇文章我想讨论的是如何在C++模板中引用传入类的一个特定的成员变量。这个特性在我们设计新型类库的时候,很是有用。我今后想讲解的无内存管理的数据容器就与这个特性相关。
比如,如果我们想设计一个通用的Hash容器,我们肯定需要提供一个选择,让用户提供它们自己的Hash函数,同时,我们也需要提供一个默认的Hash函数,因为很多时候,我们只需要使用最简单的Hash函数,比如对于整数,我们取模(“%”)。这样如下的设计浮出水面:
template<classKeyType, class ObjType, ulong32 BucketNum, class HashFcn>
classHashContainer{
};
按照前面所述,我们需要提供一个默认的Hash函数,而这个函数,我们想让它以模板参数的形式传入,所以我们肯定需要实现一个仿函数:
ClassIntergerHasher{
Public:
Ulong32 operator()(KeyType key){
Return ulong32(key%BucketNum);
}
};
好的,问题好像来了。假如现在我们有两个类,它们想使用这个容器。这两个类的定义如下:
Class A{
Private:
Ulong32 fsid; //hash键值
};
Class B{
Private:
Ulong32 volid; //hash键值
};
它们都只需要默认的hash函数就行,那么我们的Hash模板如何知道它们使用哪个域来作为hash的键值呢?
这时,我想到了函数成员指针。也许我们可以利用它。所以定义了如下的模板构造函数:
template<classKeyType, class ObjType, ulong32 BucketNum, class HashFcn>
classHashContainer{
public:
HashContainer(KeyType ObjType::*key):mKey(key), mHasher(IntergerHasher<KeyType, BucketNum>())
{}
Void add(ObjType *p);
Private:
ObjType* ObjType::*mKey;
HashFcn mHasher;
};
这里视乎还有个问题,如何使用这个成员指针呢?我们以memberfunction add()为例:
template<classKeyType, class ObjType, ulong32 BucketNum, class HashFcn>
voidHashContainer<KeyType, ObjType, BucketNum, HashFcn >::add(ObjType *p)
{
ulong32 bucket = mHasher(p->*mKey);
…..
}
我们的模板有了这个技能,就可以如此的使用这个Hash容器了:
.hxx
Class A{
Private:
Ulong32 fsid; //hash键值
Static HashContainer<ulong32,A, 1543, IntegerHasher<ulong32, 1543>) manager;
};
Class B{
Private:
Ulong32 volid; //hash键值
Static HasherContainer<ulong32,B, 1543, IntegerHasher<ulong32, 1543>) manager;
};
.cxx
HashContainer<ulong32,A, 1543, IntegerHasher<ulong32, 1543> A::manager(&A::fsid);
HashContainer<ulong32,A, 1543, IntegerHasher<ulong32, 1543> A::manager(&B::volid);
也许你们会问,我们在HashContainer中可以使用A或B的私有变量吗?可以吗?你试试!!!
如何在模板中引用参数类中的一个特定member的更多相关文章
- 转载:C++中两个类中互相包含对方对象的指针问题
原文链接:http://www.cnblogs.com/hanxi/archive/2012/07/25/2608068.html 前几天很不爽,因为C++中两个类中互相包含对方对象的指针编译时提示某 ...
- 【记录】mybatis中获取常量类中数据
部分转载,已注明来源: 1.mybatis中获取常量类中数据 <update id="refuseDebt"> UPDATE dt_debt a SET ...
- 实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法
实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法 #import <Found ...
- 尚硅谷面试第一季-11MyBatis中当实体类中的属性名和表中的字段名不一样怎么办
问题: MyBatis中当实体类中的属性名和表中的字段名不一样 ,怎么办 ? 解决方案: 1.写sql语句时起别名 <!-- id属性:必须是接口中方法的方法名 resultType属性:必须是 ...
- cc31a_demo--CppPrimer_静态成员与继承-在派生类中访问基类中的static成员的方法
//*基类中的static成员,在整个继承层次中只有一个实例 //*在派生类中访问基类中的static成员的方法 //1.基类名::成员名 //2.子类名::成员名 //3.对象.成员名 //4.指针 ...
- thymeleaf模板引擎调用java类中的方法(附源码)
前言 <Docker+SpringBoot+Mybatis+thymeleaf的Java博客系统开源啦> 由于开源了项目的缘故,很多使用了My Blog项目的朋友遇到问题也都会联系我去解决 ...
- 关于类中的参数类型和return返回值
基础有些忘了,现在重新巩固一下 先定义一个Person类 class Person(): def __init__(self,name,age,height): self.name=name, sel ...
- C#中引用参数ref和输出参数out
引用参数 用于按引用传递自变量. 为引用参数传递的自变量必须是具有明确值的变量,并且在方法执行期间,引用参数指明的存储位置与自变量相同. 引用参数使用 ref 修饰符进行声明. 输出参数 用于按引用传 ...
- Python中从B类中调用A类的方法。
好久没上了,Python还在学--最近进度有点慢... 下面代码记录了一个不太好理解的点,自己写了个小例子,总算是理顺了. B类想要调用A类,自己在网上看了一下其他人的回复:创建A类的实例,直接调用这 ...
随机推荐
- Here is a 10-line template that can solve most 'substring' problems子字符串问题的模板
转载自leetcode评论区:https://discuss.leetcode.com/topic/30941/here-is-a-10-line-template-that-can-solve-mo ...
- mysql查询语句 和 多表关联查询 以及 子查询
原文地址: http://blog.csdn.net/github_37767025/article/details/67636061 1.查询一张表: select * from 表名: 2.查询指 ...
- 面向对象设计原则 迪米特法则(Law of Demeter)
迪米特法则(Law of Demeter) 又叫作最少知识原则(Least Knowledge Principle 简写LKP),英文简写为: LoD. 这是一种面向对象程序设计的指导原则,它描述了一 ...
- 【WIN10】我的第一個WIN10-UWP應用——古文觀止
已上架,下載地址:https://www.microsoft.com/store/apps/9nblggh6cc32 特點是:繁體豎排,隱藏/顯示標點符號. 截幾張圖來瞅瞅. 1.主界面 這張圖使用的 ...
- [BZOJ4771]七彩树(主席树)
https://blog.csdn.net/KsCla/article/details/78249148 用类似经典的链上区间颜色计数问题的做法,这个题可以看成是询问DFS在[L[x],R[x]]中, ...
- codevs 1191 树轴染色 线段树区间定值,求和
codevs 1191 树轴染色 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.codevs.cn/problem/1191/ Des ...
- ios项目开发(天气预报项目):使用正则获取 weather.com.cn站点信息
NSString *pattern = @"(?<=<td class=\"bigblod\">).*?(?=</td>)"; 2 ...
- Selenium2+python自动化51-unittest简介
前言 熟悉java的应该都清楚常见的单元测试框架Junit和TestNG,这个招聘的需求上也是经常见到的.python里面也有单元测试框架-unittest,相当于是一个python版的junit. ...
- Serializable java序列化
Bean Serializable Interface 的接口让BEAN可以串行化,将其变成一个可保存为以后使用的二进制流.当一个BEAN被系列化到磁盘上或者其他任何地方,其状态被保存起来,其中的属性 ...
- jquery实现上线翻滚效果公告
//样式文件: <style type="text/css"> * { margin:; padding:; } .scrollNews { width: 100%; ...