一步步来,先简单点.

目标:我们要实现一个模板类,例化后,可以通过get_val获取到值,通过get_ptr获取到指针.具体什么意思结合例子来看看吧.

例子:

struct A{
int data;
A(int _data = 0):data(_data){}
};
template <typename T>
class heap_node{
public:
typedef T val_type;
typedef T* ptr_type;
typedef T& ref_type;
ptr_type data;
ref_type get_val() { return *data; }
ptr_type get_ptr() { return data; }
heap_node(ptr_type d) :data(d){
printf("<T> (T*)\n");
}
heap_node(ref_type d) :data(&d){
printf("<T> (T)\n");
}
}; int main() {
A a(10);
printf("ptr=%p\n",&a);
heap_node<A> p0(a);
printf("ptr=%p val=%d\n", p0.get_ptr(),p0.get_val().data);
heap_node<A> p1(&a);
printf("ptr=%p val=%d\n", p1.get_ptr(), p1.get_val().data);
/*
heap_node<A*> p2(a);
printf("ptr=%p val=%d\n", p2.get_ptr(), p2.get_val().data);
heap_node<A*> p3(&a);
printf("ptr=%p val=%d\n", p3.get_ptr(), p3.get_val().data);
*/
char ch = getchar();
}

(不要在类里直接保存值类型的数据,可以用指针或者引用都可以)

发现heap_node<A> p2(a)或者heap_node<A> p3(&a)的时候,无法正常表达我们原来的意识,此时的val_type就变成指针类型,怎么解决呢.需要对<T*>特殊处理一下.

struct A{
int data;
A(int _data = 0):data(_data){}
};
template <typename T>
class heap_node{
public:
typedef T val_type;
typedef T* ptr_type;
typedef T& ref_type;
ptr_type data;
ref_type get_val() { return *data; }
ptr_type get_ptr() { return data; }
heap_node(ptr_type d) :data(d){
printf("<T> (T*)\n");
}
heap_node(ref_type d) :data(&d){
printf("<T> (T)\n");
}
};
//<T*>偏特化
template <typename T>
class heap_node<T*>{
public:
typedef T val_type;
typedef T* ptr_type;
typedef T& ref_type;
ptr_type data;
ref_type get_val() { return *data; }
ptr_type get_ptr() { return data; }
heap_node(ptr_type d) :data(d){
printf("<T*> (T*)\n");
}
heap_node(ref_type d) :data(&d){
printf("<T*> (T)\n");
}
};
int main() {
A a(10);
printf("ptr=%p\n",&a);
heap_node<A> p0(a);
printf("ptr=%p val=%d\n", p0.get_ptr(),p0.get_val().data);
heap_node<A> p1(&a);
printf("ptr=%p val=%d\n", p1.get_ptr(), p1.get_val().data); heap_node<A*> p2(a);
printf("ptr=%p val=%d\n", p2.get_ptr(), p2.get_val().data);
heap_node<A*> p3(&a);
printf("ptr=%p val=%d\n", p3.get_ptr(), p3.get_val().data); char ch = getchar();
}

可能还有const修饰T,或者实例化T为原始数据类型......,都可能出现类似的问题,可以用偏特化解决.这里就不一一列举出来哈.

我们可以发现,特例化的<T*>模板与原模板代码上几乎一样的,是不是可以优化一下呢.

直接上代码:

struct A{
int data;
A(int _data = 0):data(_data){}
}; template <class T>
struct heap_node_type{
typedef T val_type;
typedef T* ptr_type;
typedef T& ref_type;
}; template <class T>
struct heap_node_type<T*>{
typedef T val_type;
typedef T* ptr_type;
typedef T& ref_type;
}; template <class T>
class heap_node :heap_node_type<T>{
public:
ptr_type data;
ref_type get_val() { return *data; }
ptr_type get_ptr() { return data; }
heap_node(ptr_type d) :data(d){
printf("<T> (T*)\n");
}
heap_node(ref_type d) :data(&d){
printf("<T> (T)\n");
}
}; int main() {
A a(10);
printf("ptr=%p\n",&a);
heap_node<A> p0(a);
printf("ptr=%p val=%d\n", p0.get_ptr(),p0.get_val().data);
heap_node<A> p1(&a);
printf("ptr=%p val=%d\n", p1.get_ptr(), p1.get_val().data); heap_node<A*> p2(a);
printf("ptr=%p val=%d\n", p2.get_ptr(), p2.get_val().data);
heap_node<A*> p3(&a);
printf("ptr=%p val=%d\n", p3.get_ptr(), p3.get_val().data); int b = 100;
printf("==========int====\nptr=%p\n", &b);
heap_node<int> p4(b);
printf("ptr=%p val=%d\n", p4.get_ptr(), p4.get_val());
heap_node<int> p5(&b);
printf("ptr=%p val=%d\n", p5.get_ptr(), p5.get_val()); heap_node<int*> p6(b);
printf("ptr=%p val=%d\n", p6.get_ptr(), p6.get_val());
heap_node<int*> p7(&b);
printf("ptr=%p val=%d\n", p7.get_ptr(), p7.get_val());
char ch = getchar();
}

c++ 模板 指针类型偏特化的更多相关文章

  1. C++的模板特化 和 STL中iterator_traits模板的偏特化

    C++中有类模板和函数模板,它们的定义如下所示: 类模板: template<class T1,class T2> class C { //... }; 函数模板: template< ...

  2. C++中模板的特化与偏特化

    1.引言 C++中的模板分为类模板和函数模板,虽然它引进到C++标准中的时间不是很长,但是却得到了广泛的应用,这一点在STL中有着充分的体现.目前,STL在C++社区中得到了广泛的关注.应用和研究.理 ...

  3. [转]C++中模板的特化与偏特化

    转载自:http://hi.baidu.com/klcdyx2008/blog/item/5adbf77b79f316f90bd1873c.html 1.引言C++中的模板分为类模板和函数模板,虽然它 ...

  4. 【校招面试 之 C/C++】第2题 函数模板、类模板、特化、偏特化

    1.C++模板 说到C++模板特化与偏特化,就不得不简要的先说说C++中的模板.我们都知道,强类型的程序设计迫使我们为逻辑结构相同而具体数据类型不同的对象编写模式一致的代码,而无法抽取其中的共性,这样 ...

  5. oop &&GP 模板 ---> 特化和偏特化

    OOP面向对象编程 GP泛型编程(generic programming) 两者的主要区别就是OOP将数据和对数据的操作放在一起, GP就是将数据和操作独立开来 GP:   数据就是container ...

  6. C++模板的特化与偏特化

    http://cppblog.com/SmartPtr/archive/2007/07/04/27496.html (1) 类模板定义一个栈的类模板,它可以用来容纳不同的数据类型 template & ...

  7. C++模板特化与偏特化

    C++模板 说到C++模板特化与偏特化,就不得不简要的先说说C++中的模板.我们都知道,强类型的程序设计迫使我们为逻辑结构相同而具体数据类型不同的对象编写模式一致的代码,而无法抽取其中的共性,这样显然 ...

  8. C++模板的偏特化与全特化

    模板的声明 类模板和函数模板的声明方式是一样的,在类定义/模板定义之前声明模板参数列表.例如: // 类模板 template <typename T1, typename T2> cla ...

  9. STL 全特化/偏特化

    template<class T> class Compare { public: static bool isEqual(const T& lh,const T& rh) ...

随机推荐

  1. ftp: connect: No route to host 解决方案

    实验环境: centos7 x2 server-vsftp:192.168.1.32 client:192.168.95 客户端测试访问 ftp服务器 报错:ftp: connect: No rout ...

  2. [CSharpTips]C#读取SQLite数据库中文乱码

    C#读取SQLite数据库中文乱码 C#在读取C++写入数据的Sqlite数据库中的Text内容时,会出现乱码,因为C++默认编码格式为GB2312,而Sqlite编码格式为UTF-8,存入时不统一就 ...

  3. HMS Core Discovery第17期直播预告|音随我动,秒变音色造型师

    [导读] 随着音视频内容品类的不断丰富及音乐创作门槛不断降低,大量用户正热切的参与到全民创作的大潮中.我们应该怎么去拥抱移动端影音潜力市场?音频编辑又可以有什么新玩法? 本期直播<音随我动,秒变 ...

  4. [BZOJ3625][CF438E]小朋友和二叉树 (多项式开根,求逆)

    题面 题解 设多项式的第a项为权值和为a的二叉树个数,多项式的第a项表示是否为真,即 则,所以F是三个多项式的卷积,其中包括自己: ,1是F的常数项,即. 我们发现这是一个一元二次方程,可以求出,因为 ...

  5. 并发编程二、CPU多级缓存架构与MESI协议的诞生

    ​前言: 文章内容:线程与进程.线程生命周期.线程中断.线程常见问题总结 本文章内容来源于笔者学习笔记,内容可能与相关书籍内容重合 偏向于知识核心总结,非零基础学习文章,可用于知识的体系建立,核心内容 ...

  6. django_day09_项目相关

    django_day09_项目相关 展示数据: 给模板一个querySet对象列表,循环出对象列表obj 普通字段 obj.字段名 ----> 数据库中的数据 外键 obj.外键 ------- ...

  7. 第五十八篇:webpack的Source Map

    好家伙,Source Map没听过 1.什么是Source Map? 字面意义上来看应该是个好东西 Source Map 就是一个信息文件,里面储存着位置信息. 也就是说,Source Map 文件中 ...

  8. 使用STM32控制TMC5160驱动步进电机

    首先先来了解一下TMC5160的3种工作模式 TMC5160通过两个引脚来控制它的工作模式:SD_MODE和SPI_MODE. 1.当SD_MODE接地,SPI_MODE拉高,TMC5160即工作在模 ...

  9. 从 Linux 内核角度探秘 JDK NIO 文件读写本质

    1. 前言 笔者在 <从 Linux 内核角度看 IO 模型的演变>一文中曾对 Socket 文件在内核中的相关数据结构为大家做了详尽的阐述. 又在此基础之上介绍了针对 socket 文件 ...

  10. Sync包

    sync同步包 Mutex互斥锁: 能够保证在同一时间段内仅有一个goroutine持有锁,有且仅有一个goroutine访问共享资源,其他申请锁的goroutine将会被阻塞直到锁被释放.然后重新争 ...