使用模版元编程实现C和C++中复杂类型声明的语义化

来源:互联网 发布:hp1505n网络打印设置 编辑:程序博客网 时间:2024/05/22 09:37

背景

C和C++中提供的基本类型总共有13中,定义在limit头文件中。如下:

//整数类型boolchar | signed char | unsigned charshort | unsigned shortint | unsigned intlong | unsigned long//浮点类型floatdoublelong double

除此之外,C++还定义了两种新的长整数类型:

long long | unsigned long long

针对这些基本类型,然后使用复合类型进行组合,会得到很多复杂的声明式。复合类型有:

[] //数组*  //指针&  //引用() //函数const //常量修饰

对于理解复杂声明需要深入理解各个复合运算的规则,这是一种较难入手学习的点,这里使用模版元编程的技术,充分利用编译器对复杂声明进行的计算过程,得出每个复杂声明的语义化描述,不仅能加深对编译器解析复杂声明的理解,也能练习模版元编程的技术。

实现

使用一个type_descriptor的模版类来实现,对于基本类型使用全特化版本输出,对于复杂类型使用偏特化进行实现。源码如下:

#include <iostream> template<typename T>struct type_descriptor{    type_descriptor(){}};//fully specializationtemplate<>struct type_descriptor<bool>{    type_descriptor(){ std::cout << "bool"; }};template<>struct type_descriptor<char>{    type_descriptor(){ std::cout << "char"; }};template<>struct type_descriptor<unsigned char>{    type_descriptor(){ std::cout << "unsigned char"; }};template<>struct type_descriptor<signed char>{    type_descriptor(){ std::cout << "signed char"; }};template<>struct type_descriptor<int>{    type_descriptor(){ std::cout << "int"; }};template<>struct type_descriptor<unsigned int>{    type_descriptor(){ std::cout << "unsigned int"; }};template<>struct type_descriptor<long>{    type_descriptor(){ std::cout << "long"; }};template<>struct type_descriptor<unsigned long>{    type_descriptor(){ std::cout << "unsigned long"; }};template<>struct type_descriptor<long long>{    type_descriptor(){ std::cout << "long long"; }};template<>struct type_descriptor<unsigned long long>{    type_descriptor(){ std::cout << "unsigned long long"; }};template<>struct type_descriptor<float>{    type_descriptor(){ std::cout << "float"; }};template<>struct type_descriptor<double>{    type_descriptor(){ std::cout << "double"; }};template<>struct type_descriptor<long double>{    type_descriptor(){ std::cout << "long double"; }};//partial specializationtemplate<typename T>struct type_descriptor<T*>{    type_descriptor()    {       std::cout << "pointer to ";       type_descriptor<T>();    }};template<typename T>struct type_descriptor<T&> {    type_descriptor()    {        std::cout << "reference of ";        type_descriptor<T>();    }};template<typename T>struct type_descriptor<const T>{    type_descriptor()    {        std::cout << "const ";        type_descriptor<T>();    }};template<typename T>struct type_descriptor<T[]>{    type_descriptor()    {        std::cout << "array of ";        type_descriptor<T>();    }};template<typename T>struct type_descriptor<T()>{    type_descriptor()    {        std::cout << "function returning ";        type_descriptor<T>();    }};

测试代码如下:

int main(int argc, char ** argv){    type_descriptor<char*>();    std::cout << '\n';    type_descriptor<char * &>();    std::cout << '\n';    type_descriptor<double const * const(*[])()>();    std::cout << '\n';    return 0;}

测试的三个声明中逐渐复杂,第一个是指针char *,第二个是指针的引用char * &,但是第三个声明就很复杂了,这个复杂的声明需要编译器去解析,熟悉这个过程的朋友肯定知道,先从内往外一层层来解析。下面是运行结果:

pointer to charreference of pointer to chararray of pointer to function returning const pointer to const double

对于不熟悉第三复杂声明的解析过程的朋友,可以很容易从上述运行结果中看出来,这个声明本质上是一个数组,数组中每个元素都是一个指向函数的指针,每个函数返回的是一个double类型的常量指针并且这个返回的指针本身也是一个常量(const pointer to const double)。
有需要的朋友可以拿去一用~_~

0 0
原创粉丝点击