一步步来,先简单点.

目标:我们要实现一个模板类,例化后,可以通过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. TS 泛型推断好难啊,看看你能写出来不

    前言 最近做东西都在用ts,有时候写比较复杂的功能,如果不熟悉,类型写起来还是挺麻烦的.有这样一个功能,在这里,我们就不以我们现有的业务来举例了,我们还是已Animal举例,来说明场景.通过一个工厂来 ...

  2. 论文解读(PairNorm)《PairNorm: Tackling Oversmoothing in GNNs》

    论文信息 论文标题:PairNorm: Tackling Oversmoothing in GNNs论文作者:Lingxiao Zhao, Leman Akoglu论文来源:2020,ICLR论文地址 ...

  3. echarts学习笔记(一)

    echarts学习笔记(一) echarts开发步骤 创建一个新的html文件 在html文件head头部信息中导入echarts 声明一个容器(可以理解为画布),用于存放echarts 实例化ech ...

  4. RTSP鉴权认证之基础认证和摘要认证区别

    RTSP认证类型 基本认证(basic authentication):http 1.0提出的认证方案,其消息传输不经过加密转换因此存在严重的安全隐患.: 摘要认证(digest authentica ...

  5. K8S name_namespace

    Name 由于K8S内部,使用"资源"来定义每一种逻辑概念(功能),故没种"资源",都应该有自己的"名称" "资源"有 ...

  6. filebeat客户端传输cisco日志到elasticsearch

    一.安装相应版本的filebeat wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.5.2-x86_64.r ...

  7. Windows服务器无法配置IP

    前天在给一台服务器配置IP地址的时候发现一个奇怪的问题.IP地址配置之后不生效,还是使用的169.254这个微软保留自动分配地址.由于这个是一台虚拟机,尝试了删除添加网卡也没有用.配置IP不成功的时候 ...

  8. Scrum五大会议要怎么开?

    在Scrum框架中,我们对Scrum的五个会议一定都不陌生,但如何组织这五个会议,才能让Scrum团队真正积极.主动地参与进项目管理中呢?接下来我们会以一个Sprint为周期,详细介绍一下Sprint ...

  9. 使用docker-compose运行nginx容器挂载时遇到的文件/目录问题

    单独使用docker run命令指定挂载文件路径运行nginx容器是可以的,但是用在docker-compose中就不行了 报错如下: 原因就是挂载出错,不能直接挂载文件,还有挂载的容器里的目录要正确 ...

  10. nacos基础知识理解

    概念 Nacos是阿里巴巴开源的一款支持服务注册与发现,配置管理以及微服务管理的组件.用来取代以前常用的注册中心(zookeeper , eureka等等),以及配置中心(spring cloud c ...