如何在模板中引用参数类中的一个特定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类的实例,直接调用这 ...
随机推荐
- .Net中的IO
C#中的IO 本文环境为: Win 10 VS 2015 .net Framework 版本 4.0 File 类 File 类是一个工具类,可以用来判断文件是否存在和方便的创建文件, 读取.写入等操 ...
- PYQT窗口居中
#UI.py,通过UI设计师制作后直接转换为UI.py脚本 # -*- coding: utf-8 -*-from PyQt4 import QtCore, QtGui try: _fromUt ...
- Codeforces Round #296 (Div. 1) B. Clique Problem 贪心
B. Clique Problem time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- 读书笔记_Effective_C++_条款三十五:考虑virtual函数以外的其他选择
举书上的例子,考虑一个virtual函数的应用实例: class GameCharacter { private: int BaseHealth; public: virtual int GetHea ...
- Android WebView H5开发拾遗
上篇介绍了一些WebView的设置,本篇为一些补充项. 首先加载HTML5的页面时,会出现页面空白的现象,原因是需要开启 DOM storage API 功能: webSettings.setDomS ...
- QN-H618 遥控器复制再生仪(拷贝机)
针对现在市场上日益更新的遥控器种类,本公司经过长时间的研究,推出新一代拷贝机,本产品有以下特点: 1. 众多车库门遥控分析信息被集成在一台机器内,只要一种遥控器,就可以复制众多品牌的车库遥控.免去积压 ...
- mysql 源代码编绎
http://blog.chinaunix.net/uid-20723616-id-769326.html https://software.intel.com/zh-cn/blogs/2010/08 ...
- Effective JavaScript Item 35 使用闭包来保存私有数据
本系列作为EffectiveJavaScript的读书笔记. JavaScript的对象系统从其语法上而言并不鼓舞使用信息隐藏(Information Hiding).由于当使用诸如this.name ...
- java程序的运行方式
1.JAR File JAR 文件用于压缩和发布,而且还用于部署和封装库.组件和插件程序,并可被像编译器和 JVM 这样的工具直接使用 有点类似于net中的dll 2.Runnable JAR Fil ...
- Android之LogUtil
提供debug与release的时候是否屏蔽打印信息,把信息选择性的进行保存,可以是否自动保存crash的堆栈信息.来自github上的一个开源项目,https://github.com/syxc/L ...