首页 > 编程语言 >C++范型三:数据类型表

C++范型三:数据类型表

时间:2024-10-31 17:31:29浏览次数:7  
标签:范型 typedef 数据类型 value C++ template type 模板

类的数据类型成员

C++中,在类模板中用typedef定义的数据类型称为内嵌类型nested type

template<typename T>
class MyTraits{
public:
    typedef T mytype;
};

如下,使用内嵌类型在类外定义变量

typename MyTraits<int>::mytype n;

可知,类外引用类模板的公有类型成员和引用类静态成员的写法相同,为了区分,在引用类型成员时需用关键字typename表明

typedef

为现有类型定义别名,增加程序可读性,还简化复杂的类型名
如类型void (*b[10])(void(*)()),变量名为b
先替换右边部分括号

typedef void(*pFunParam)()

再替换左边的变量b

typedef void(*pFunx)(pFunParam)

原声明可简化为

pFunx b[10]

typedef最大的用处是编写平台无关代码,如typedef unsigned int uint32,跨平台时,只需要维护typedef即可

内嵌数据类型表和数据类型衍生

为了方便,将typedef定义的所有公有数据类型及其衍生类型定义在一个类模板中形成一个数据类型表

typedef T value_type;
typedef T& reference;
typedef T* pointer;

数据类型表

若一个类模板中,全部成员都是公有数据类型,那这个类模板称为独立数据类型表,简称数据类型表,数据类型表可以规范代码的模板类型,是STL库用以规范代码的主要手段

如下数据类型表

template<typename T>
class TypeTb{
public:
    typedef T value_type;
    typedef T* pointer_type;
    typedef T& reference_type;
};

定义一个类模板,继承自数据类型表

template<typename T>
class Num::public TypeTb<T>{
    // todo:
};

使用继承自数据类型表的类模板

void func(
    Num<int>::value_type x,
    Num<int>::reference_type y,
    Num<int>::pointer_type z){
        cout<< "x="<< x<<endl;
        cout<< "y=x="<< y<<endl;
        cout<< *z<<endl;
}

此时会发现一个问题,函数func的形参类型是固定的,如何将该函数用模板定义

// 错误实现
template<typename T>
void func(T<int>::value_type x, T<int>::reference_type y, T<int>::pointer_type z){
    cout<< "x="<< x<<endl;
    cout<< "y=x="<< y<<endl;
    cout<< *z<<endl;
}

该函数模板中,类型占位符T占的位置是Num,而Num不是类型,可知,类型占位符不是字符串上的简单替换

// 正确实现
template<typename T>
void func(
    typename T::value_type x,
    typename T::reference_type y,
    typename T::pointer_type z){
        cout<< "x="<< x<<endl;
        cout<< "y=x="<< y<<endl;
        cout<< *z<<endl;
}
/*
使用方式为:
typename Num<int>::value_type a= 100;
func<Num<int>>(a, a, &a);
*/

可以看出,类型占位符代表的真正类型是Num<int>

特化数据类型表

为了满足对于不同类型,有相同定义的场景,如:

class T1{
public:
    int compute(char x, double y){ return x; }
};

class T2{
public:
    double compute(double x, int y){ return x; }
};

定义一个特化数据类型表

class type1;
class type2;

template<typename T>
class TypeTb{};

template<>
class TypeTb<type1>{
public:
    typedef int ret_type;
    typedef char para1_type;
    typedef double para2_type;
};

template<>
class TypeTb<type2>{
public:
    typedef double ret_type;
    typedef double para1_type;
    typedef int para2_type;
};

为了将上述有类似定义的函数,使用不提供多个模板参数的模板实现,可结合特化数据类型表,实现如下:

template<typename T>
class Test{
public:
    typename TypeTb<T>::ret_type compute(
        typename TypeTb<T>::para1_type x, typename TypeTb<T>::para2_type y){
            return x;
    }
};
/*
test:
Test<type1> t1;
// t1.compute();

Test<type2> t2;
// t2.compute();
*/

STL中的Traits表

Traits实质上是特化数据类型表在STL中的一个具体应用,也是数据类型表,因其构思巧妙,而被称为Traits技巧

STL中用来指示数据位置的迭代器对象,大多数是包含内嵌数据类型表的类模板,从而能向外提供类型

C++指针也是用来指示数据位置的,理论上也属于迭代器范畴,为了接口的统一,指针也应该向外提供数据类型
使用特化模板实现指针的数据类型表

// 指针的特化模板
template<typename T>
struct Traits<T*>{ // 此时的 T 不是指针类型
    typedef T value_type;
    typedef value_type* pointer;
    typedef value_type& reference;
};

/*
test:
Traits<double*>::value_type t=2;
*/

使用特化数据类型表解决了原生类型的数据类型表问题,但是各个迭代器的数据类型表分散于各个迭代器类中,在管理上造成麻烦,此时可用一个迭代器类型表的总表解决该问题,即Traits表

template<typename T>
struct Iterator1{
    typedef T value_type;
    typedef value_type* pointer;
    typedef value_type& reference;
    ...
};
template<typename T>
struct Iterator2{
    typedef T value_type;
    typedef value_type* pointer;
    typedef value_type& reference;
    ...
};

// 类型总表
template<typename T>
struct Traits{
    typedef typename T::value_type value_type;
    typedef typename T::pointer pointer;
    typedef typename T::reference reference;
};

template<typename T>
struct Traits<T*>{
    typedef T value_type;
    typedef value_type* pointer;
    typedef value_type& reference;
};

/*
test:
Traits<Iterator_1<int>>::value_type t=2;
Traits<Iterator_2<double>>::value_type t=2;
Traits<double*>::value_type t=2;
*/

标签:范型,typedef,数据类型,value,C++,template,type,模板
From: https://www.cnblogs.com/sgqmax/p/18518503

相关文章

  • C/C++中的指针详解(重点)
    指针是C和C++中一个重要且强大的特性。它们允许程序员直接访问和操作内存,提供了灵活的内存管理和高效的数据结构实现。对一个变量取*操作其实就是取到这个变量的地址,然后再对取到的变量进行读写等操作以下是对指针的详细介绍:1.什么是指针指针是一个变量,它存储另一个变量的......
  • 【C++】01-C++ 程序的生成过程
    概要:该篇文章以MSCV为例,简要介绍了C++程序的生成过程。1.生成工具MSVC,全称MicrosoftVisualC++,是由微软开发的用于生成C++程序的工具集,包括C++预处理器、编译器、链接器和其他生成工具。2.生成过程2.1预处理(Preprocess)预处理由预处理器(Preprocessor)......
  • C++ halcon判断图像是否为空
    使用CountObj函数首先,可以使用CountObj函数来检查当前图像是否为空。如果图像为空,则返回的计数为0;否则,返回的计数大于0。示例代码如下:cppCopyCode HTuplehNum;HalconCpp::CountObj(m_hCurrentImg,&hNum);if(hNum==0){qDebug()<<"传入图像为空!";}else{qDebu......
  • Python数据类型之自定义类型——Class与面向对象编程详解
    目录引言一、面向对象编程基础二、类的定义与对象的创建三、封装性四、继承性五、多态性六、特殊方法与数据类七、使用dataclass装饰器八、面向对象编程的优势结论引言Python是一门功能强大的编程语言,其面向对象编程(OOP)的特性更是为开发者提供了极大的灵活性和......
  • 数据类型
    java:buteshortintlongmysql: tinyint(m) --m:限定拆线呢的时候的宽度tinyint--->byte tingintunsigned无符号  0-255tingint(1)--->booleanofalse1ture常用2个整数类型bigint(m)->java中long类型时间毫秒数int(5)zerofill:以0填充7.2浮点类型folat......
  • 【C++】红黑树的插入与删除
    第一篇数据结构学习之红黑树的实现系列文章目录前言一、红黑树的基本概念二、参考视频链接三、代码实现1.定义节点类2.旋转方法3.红黑树插入操作4.红黑树删除操作四,总体代码总结系列文章目录第一篇数据结构学习之红黑树的实现前言红黑树是一种平衡二叉搜索树,在......
  • C++——写一函数,将一个3x3的整型矩阵转置。用指针或引用方法处理。
    没注释的源代码#include<iostream>usingnamespacestd;voidmove(int*p);intmain(){  inta[3][3],*p;  cout<<"pleaseinputmatrix:"<<endl;  for(inti=0;i<3;i++)  {    for(intj=0;j<3;j++)    {     ......
  • C++——将一个5x5的矩阵中最大的元素放在中心,4个角分别放4个最小的元素(按从左到右、
    没注释的源代码#include<iostream>#include<stdio.h>#include<string.h>usingnamespacestd;voidtransform(int*arry,intcol_row);intmain(){   intarry[5][5];   cout<<"Pleaseentera5x5matrix:"<<endl;   for(......
  • C++(std::to_string())
    目录1.函数定义2.示例代码3.内部实现机制4.注意事项5.应用场景6.使用std::ostringstream控制精度的示例7.总结std::to_string()是C++11引入的一个标准库函数,用于将基本数据类型(如整数、浮点数等)转换为对应的字符串格式。这个函数属于<string>头文件,因此使用时需......
  • 【C++】深究类型转换
    ⭐️个人主页:@小羊⭐️所属专栏:C++很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎~目录一、类型转换1、C语言中的类型转换2、C++中的类型转换3、C语言类型转换的缺陷4、C++中的四种强制类型转换4.1static_cast4.2reinterpret_cast4.3const_cast4.4dynam......