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