博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
学习C++模板元编程(1)
阅读量:3604 次
发布时间:2019-05-21

本文共 4438 字,大约阅读时间需要 14 分钟。

 
3183人阅读 
(0) 
 
  
TAOCP没看多久,觉得里面的数学知识太深了,离开学校多年,很多基础知识已记不起来了,学起来有点累,所以结束了TAOCP的学习,转到了《C++ Template Metaprogramming》。
刚看完书中的第二章,关于 Type traits的,习题中有一条比较有趣,就是模仿cdecl命令将一个C++的类型用pseudo-English(伪英语)描述出来,例如:对于 char *(*[])() ,输出“array of pointer to function returning pointer to char” 。
程序如下:
#include <iostream>
#include <cstring>
 
const int MAXLEN_TYPE_DESCRIPTOR = 200;
 
template <typename T>
struct type_descriptor
{
    operator const char*()
    {
        return name_;
    }
    static const char* name_;
};
 
template <typename T>
const char* type_descriptor<T>::name_ = "Unkown type";
 
template <>
const char* type_descriptor<char>::name_ = "char";
 
template <>
const char* type_descriptor<short>::name_ = "short";
 
template <>
const char* type_descriptor<int>::name_ = "int";
 
template <>
const char* type_descriptor<long>::name_ = "long";
 
template <>
const char* type_descriptor<long long>::name_ = "long long";
 
template <>
const char* type_descriptor<unsigned char>::name_ = "unsigned char";
 
template <>
const char* type_descriptor<unsigned short>::name_ = "unsigned short";
 
template <>
const char* type_descriptor<unsigned int>::name_ = "unsigned int";
 
template <>
const char* type_descriptor<unsigned long>::name_ = "unsigned long";
 
template <>
const char* type_descriptor<unsigned long long>::name_ = "unsigned long long";
 
template <>
const char* type_descriptor<float>::name_ = "float";
 
template <>
const char* type_descriptor<double>::name_ = "double";
 
template <>
const char* type_descriptor<long double>::name_ = "long double";
 
template <>
const char* type_descriptor<void>::name_ = "void";
 
template <>
const char* type_descriptor<bool>::name_ = "bool";
 
这一段代码先定义了type_descriptor的主模板,它有一个类型转换操作符函数和一个指向类型描述字符串的静态常量字符指针。operator const char*()使得该类型可以直接用于流输出,如:cout << type_descriptor<…>(); 接下来的代码定义了主模板所使用的静态常量字符指针,它指向“Unknown type”,如果type_descriptor被实例化时未能使用特化的模板,则会得到这个“Unknown type”的描述。再往下,是针对15个C++基本类型(fundamental types)的type_descriptor特化版本的静态常量字符指针定义,分别指向了各自的描述串。
定义完了基本类型的特化版本,现在轮到复合类型(compound types)及带CV限定符的类型,程序如下:
template <typename T>
struct type_descriptor<T*>
{
    operator const char*()
    {
        static char name[MAXLEN_TYPE_DESCRIPTOR];
        strcpy(name, "pointer to ");
        strcat(name, type_descriptor<T>());
        return name;
    }
};
 
template <typename T>
struct type_descriptor<T&>
{
    operator const char*()
    {
        static char name[MAXLEN_TYPE_DESCRIPTOR];
        strcpy(name, "reference to ");
        strcat(name, type_descriptor<T>());
        return name;
    }
};
 
template <typename T>
struct type_descriptor<T const>
{
    operator const char*()
    {
        static char name[MAXLEN_TYPE_DESCRIPTOR];
        strcpy(name, type_descriptor<T>());
        strcat(name, " const");
        return name;
    }
};
 
template <typename T>
struct type_descriptor<T volatile>
{
    operator const char*()
    {
        static char name[MAXLEN_TYPE_DESCRIPTOR];
        strcpy(name, type_descriptor<T>());
        strcat(name, " volatile");
        return name;
    }
};
 
template <typename T>
struct type_descriptor<T[]>
{
    operator const char*()
    {
        static char name[MAXLEN_TYPE_DESCRIPTOR];
        strcpy(name, "array of ");
        strcat(name, type_descriptor<T>());
        return name;
    }
};
 
template <typename R>
struct type_descriptor<R (*)()>
{
    operator const char*()
    {
        static char name[MAXLEN_TYPE_DESCRIPTOR];
        strcpy(name, "pointer to function returning ");
        strcat(name, type_descriptor<R>());
        return name;
    }
};
 
template <typename R, typename A>
struct type_descriptor<R (*)(A)>
{
    operator const char*()
    {
        static char name[MAXLEN_TYPE_DESCRIPTOR];
        strcpy(name, "pointer to function with ");
        strcat(name, type_descriptor<A>());
        strcat(name, " returning ");
        strcat(name, type_descriptor<R>());
        return name;
    }
};
 
这一段代码分别处理了指针、引用、数组、CV限定符,以及无参函数、单参函数等类型的偏特化。每个偏特化版本都定义了各自的operator const char*(),其中各有一个本地静态字符数组用于存放各自的类型描述串,该描述串递归地由更基本类型的type_descriptor模板加上特定的字符串(如“pointer of ”、“reference of”、“array of”等)生成。
最后是测试用的main()及运行结果,如下:
int main()
{
    std::cout << type_descriptor<int>() << std::endl;
    std::cout << type_descriptor<char*>() << std::endl;
    std::cout << type_descriptor<short const*&>() << std::endl;
    std::cout << type_descriptor<long const* volatile>() << std::endl;
    std::cout << type_descriptor<char *(*[])()>() << std::endl;
    std::cout << type_descriptor<char *(*[])(int&)>() << std::endl;
    return 0;
}
 
Output:
int
pointer to char
reference to pointer to short const
pointer to long const volatile
array of pointer to function returning pointer to char
array of pointer to function with reference to int returning pointer to char
 
当然,这个type_descriptor还有很多不足的地方,如:描述串长度有限、没有考虑更多参数的函数类型、没有考虑用户自定义类型等。

转载地址:http://okxzn.baihongyu.com/

你可能感兴趣的文章
2019/01/11 查找文件
查看>>
2019/0/12 查找文件和压缩
查看>>
2019/01/13 sed企业应用
查看>>
2019/01/15 sed高级用法和软件包管理
查看>>
2019/01/16 RPM包软件管理01
查看>>
2019/01/17 YUM包软件管理01
查看>>
2019/01/19 YUM包软件管理02
查看>>
2019/01/19 编译安装httpd
查看>>
2019/01/20 编译安装httpd和磁盘管理
查看>>
2019/01/20 磁盘管理MBR分区表
查看>>
计算机基础和linux目录
查看>>
2019/01/21 磁盘管理分区
查看>>
linux echo命令换行写入文件
查看>>
2019/01/22 文件系统管理
查看>>
2019/01/23 文件系统管理和挂载
查看>>
2019/01/24 文件系统管理挂载上
查看>>
2019/01/24 文件系统管理挂载下
查看>>
2019/01/25 swap文件系统管理
查看>>
2019/01/26 外围设备使用
查看>>
2019/01/26 raid工作原理
查看>>