学习C++模板元编程(1)

学习C++模板元编程(1)

  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还有很多不足的地方,如:描述串长度有限、没有考虑更多参数的函数类型、没有考虑用户自定义类型等。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值