到底什么是type traits

rType Traits 是c++模板编程中使用的比较巧妙的一种技术,这种技术可以让你获取或者转换模板的类型属性。

我们从一个具体的需求开始分析,我们想在一个模板函数中获取模板的具体类型,针对不同的具体类型,有一些特殊的处理。

比如:一个模板函数 template<typename T> void decode(const T& data,char* buf),我们允许这个函数在不同的类型实例化的时候,有不同的处理。

template<typename T> void decode(const T& data,char* buf)
{
   switch(T):
    {
        case "int":
            cout<<"int"<<endl
            break;
        case "float":
            cout<<"float"<<end;
        break;
        ...
        default:
            cout<<"unknow customed type";
            break;
    }

}

我们先定义类型列表:

enum Type {
  TYPE_1=1,     //Foo
  TYPE_2,       //int
  TYPE_3,   // float
  TYPE_4    // unknown
};

然后再创建一个模板类,等模板类实例化的时候,里面包含实例化的类型。比如说,如果用int来为T实例化的时候,我们的type就赋值为TYPE_2,依次类推。

template <typename T>
struct type_traits
{
    public:
     static const Type type=T::type;
};

我们把这个类模板引入到我们的模板函数中:

template<typename T>
void decode(const T& data,char* buf) {
    switch (type_traits<T>::type)
    {
        case Type::TYPE_1:
            cout<<"Foo"<<endl;
            break;
        case Type::TYPE_2:
            cout<<"int"<<endl;
            break;
        case Type::TYPE_3:
            cout<<"float"<<endl;
            break;
        default:
            cout<<"unknown"<<endl;
            break;
    }

}

模板的类型既有系统内置的类型,比如 int,float,也有我们自己定义的类型,比如Foo和Bar等。

我们对内置类型进行类模板的偏特例化,这样模板函数中的type_traits<T>::type变量就对应这两个特例化中的type类型

template<>
struct type_traits<int> {
  static const Type type = Type::TYPE_2;
};
template<>
struct type_traits<float> {
  static const Type type = Type::TYPE_3;
};

那么如果类型是我们自己定义的类型,我们该如何描述各自的类型:比如Foo和Bar类分别制定为TYPE_3和TYPE_4.

class Foo {
public:
   static const Type type = Type::TYPE_1; 
};
class Bar {
public:
   static const Type type = Type::TYPE_4; 
};

以Foo为例,type_traits模板类就会特例化为如下代码,static const Type type=Foo::type=Type::TYPE_1;

template <>
struct type_traits<Foo>
{
    public:
     static const Type type=Foo::type;
};

如此就巧妙地把内置类型和自定义类型使用同样的代码进行了处理,完整的运行代码如下:

#include<iostream>
using namespace std;
enum Type {
  TYPE_1=1,     //Foo
  TYPE_2,       //int
  TYPE_3,   // float
  TYPE_4    // unknown
};


template <typename T>
struct type_traits
{
    public:
     static const Type type=T::type;
};

class Foo {
public:
   static const Type type = Type::TYPE_1; 
};
class Bar {
public:
   static const Type type = Type::TYPE_4; 
};

template<>
struct type_traits<int> {
  static const Type type = Type::TYPE_2;
};
template<>
struct type_traits<float> {
  static const Type type = Type::TYPE_3;
};

template<typename T>
void decode(const T& data,char* buf) {
    switch (type_traits<T>::type)
    {
        case Type::TYPE_1:
            cout<<"Foo"<<endl;
            break;
        case Type::TYPE_2:
            cout<<"int"<<endl;
            break;
        case Type::TYPE_3:
            cout<<"float"<<endl;
            break;
        default:
            cout<<"unknown"<<endl;
            break;
    }
}
int main()
{
    char* p;
    Foo foo;
    decode(foo,p);
    Bar bar;
    decode(bar,p);
    int a;
    decode(a,p);
    float d;
    decode(d,p);
    return 1;
}

type_traits 称为类型萃取技术,主要用于编译期获取某一参数、某一变量、某一个类等等任何 C++相关对象的类型,以及判断他们是否是某个类型,两个变量是否是同一类型,是否是标量、是否是引用、是否是指针、是左值还是右值,还可以将某个为某个类型去掉 cv(const volitale)属性或者增加 cv 属性等等

从c++ 11开始,c++提供了大量的type_traits的模板类,来实现各种功能,具体请看Standard library header <type_traits> (C++11) - cppreference.com

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值