如何在模板中引用参数类中的一个特定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类的实例,直接调用这 ...
随机推荐
- 关于socket知识整理
一个完整的计算机系统是由硬件.操作系统.应用软件三者组成,具备了这三个条件,一台计算机系统就可以玩单机游戏.如果你想上网(访问个黄色网站,发个黄色微博啥的),就需要遵守网络协议,即计算机之间交流的标准 ...
- [HihoCoder1596]Beautiful Sequence
题目大意: \(n(n\le60)\)个数\(A_{1\sim n}\),将这些数随机打乱,问最后构成的数列满足对于所有的\(2\le i\le n-1\),都有\(2A_i\le A_{i-1}+A ...
- 2016 UESTC Training for Data Structures 题解
题解在下已经写过一次了,所以就不再写了,下面只有代码 题解下载(1):http://pan.baidu.com/s/1hsAUjMs 题解下载(2):http://pan.baidu.com/s/1m ...
- Windows下ftp服务器搭建及配置
Win系统使用ser-u软件进行FTP服务器的搭建下载地址:https://www.serv-u.com/操作步骤如下:1. 点击执行程序进行按照SU-FTP-Server-Windows-v15.1 ...
- 理解linux下源码、yum和rpm安装方法的特点
1.yum可看作在线安装,只需yum install 软件名,系统就自动根据yum源配置文件中的镜像位置去下载安装包,并可以自动分析所需的软件依赖关系,自动安装所需的依赖软件包.简单方便,不易出错,不 ...
- 华为S5300系列交换机V100R005SPH008热补丁
S23_33_53-V100R005SPH008.pat 附件: 链接:https://pan.baidu.com/s/1XfIQ55g5pWI9aqmM7LHUew 密码:f2mu
- Javascript 面向对象编程(一):封装(转载)
Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类). 那么,如果 ...
- java基础学习总结——网络编程
一.网络基础概念 首先理清一个概念:网络编程 != 网站编程,网络编程现在一般称为TCP/IP编程.
- PhotoShop CS6 在2K屏幕下标题菜单等字体太小
对于此类问题,我更喜欢直接了当,不作解释,解决方法如下(大面积参考互联网内容): (1)Win+R按键打开运行对话框, 输入regedit,打开注册表. (2)展开HKEY_LOCAL_MACHINE ...
- [转载] 关于matlab GUI的一点心得
转载自 落落轻尘 [Fig文件方式,即使用菜单File->New->GUI来设计界面] 首先值得注意的是,在低版本matlab上制作的含GUI的m文件一般不能在高版本的matlab上面运行 ...