类模板以及其中的traits技术和type classification技术
来源:互联网 发布:淘宝这那样下架商品 编辑:程序博客网 时间:2024/06/01 09:59
1. 类模板相关概念
类模板用来描述一系列具有相同行为的类。一般有如下的形式:
template<class T, class U>class A{public:A(){ cout<<"Primary template\n";}private: T t; U u; };
如上所示的类模板我们一般称之为主类模板。
实例化后的类模板称之为特化模板类,当我们全部的模板类型时,如下全部给定了T和U的类型时,,
template<>class A<int, int>{public: A() { cout <<"<int, int> Fully specialization\n"; }private: int t; int u; };这称之为完全特化。当部分指定了类模板的参数类型时,称之为偏特化,如下所示,
template<class T>class A<T, T>{public: A() { cout <<"<T,T> partial specialization\n";}private: T t; T u;};当我们由一个类模板创建实例对象时,创建对象采用的模板类的匹配顺序为完全特化模板类-->偏特化模板类-->主类模板,示例如下:
#include <iostream>using namespace std;template<class T, class U>class A{public: A(){ cout<<"Primary template\n";}private: T t; U u;};template<>class A<int, int>{public: A() { cout <<"<int, int> Fully specialization\n"; }private: int t; int u;};/* *template<> *class A<int, float> *{ *public: * A() { cout <<"<int, float> Fully specialization\n"; } *}; */template<class T, class U>class A<T*, U>{public: A() { cout <<"<T*,U> partial specialization\n";}private: T t; U u;};template<class T>class A<T, T>{public: A() { cout <<"<T,T> partial specialization\n";}private: T t; T u;};template<class U>class A<int, U>{public: A() { cout <<"<int,U> partial specialization\n";}private: int t; U u;};int main(){ A<char,int> a1; A<char*,int> a2; A<float,float> a3; A<int, float> a4; A<int, int> a5; return 0;}输出:Primary template<T*,U> partial specialization<T,T> partial specialization<int,U> partial specialization<int, int> Fully specialization
从上面的代码我们发现,采用不同的参数实例化出来的类具有不同的特征,但是他们可以有相同的接口,利用这一点,我们可以将不同数据类型的特征封装在一个类模板中,程序其它模块可以使用这个类模板的接口,获得每个数据类型的特征信息。这就是所谓的Traits技术。
2. Traits技术
Ttraits在中文中称之为特性,Traits技术以一个统一的编程接口,描述各个数据类型的基本特征。例如,float和double能够表示的最小正数一般定义为常量FLT_EPSILON和DBL_EPSILON. 如果我们在一个数值库中分别要用到float和double, 在需要获得某个变量的特性时都要检查该变量的类型,非常麻烦。如果采用Traits技术,我们则可以用统一的接口来获取这些差异化的特性。
例如:
#include <iostream>#include <float.h>using namespace std;template <typename numT>struct fp_traits { };template<>struct fp_traits<float> { typedef float fp_type; enum { max_exponent = FLT_MAX_EXP }; static inline fp_type epsilon() { return FLT_EPSILON; }};template<>struct fp_traits<double> { typedef double fp_type; enum { max_exponent = DBL_MAX_EXP }; static inline fp_type epsilon() { return DBL_EPSILON; }};template <typename numT>class matrix {public: typedef numT num_type; typedef fp_traits<num_type> num_type_info; inline num_type epsilon() { return num_type_info::epsilon(); } //...};int main(){ matrix <float> fm; matrix <double> dm; cout << "float matrix: " << fm.epsilon() << endl; cout << "double matrix: " << dm.epsilon() << endl;}
3. type classification技术
根据C++专家Water E.Brown的说法,C++中一般有如下14种类型:
template <class T> struct is_void;template <class T> struct is_null_pointer; //<- arrived in C++11 (std::nullptr_t)template <class T> struct is_integral;template <class T> struct is_floating_point;template <class T> struct is_array;template <class T> struct is_pointer;template <class T> struct is_lvalue_reference;template <class T> struct is_rvalue_reference;template <class T> struct is_member_object_pointer;template <class T> struct is_member_function_pointer;template <class T> struct is_enum;template <class T> struct is_union;template <class T> struct is_class;template <class T> struct is_function;但是C++中和类型相关的运算符仅有sizeof, dynamic_cast, typeid等,他们在获取C++类型信息时非常有限,正是因为如此,我们可以基于类模板特化技术,设计专门的类模板来提供所需的信息,这种方法为类型分类(type classification)技术。
设想有一个这样的任务:模板参数T可能是指针类型,引用类型或者数组(包括vector)中的某一种,我们需要判断T究竟是哪一个。如果是指针类型,需要知道该指针所指的类型,我们称为baseT,还需要该类型最底层的类型是哪个C++类型,我们称为bottomT; 比如对于指针类型int**, baseT为int *;bottomT为int; 对于数组类型,我们还希望可以获得其维数。
下面的示例代码利用type classification技术很好的解决了这一问题:
#include <iostream>#include <vector>using namespace std;template<typename T>class TypeInfo {public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0 }; enum { Dim = 0 }; typedef T baseT; typedef T bottomT;};template<typename T>class TypeInfo<T*> {public: enum { IsPtrT = 1, IsRefT = 0, IsArrayT = 0 }; enum { Dim = 0 }; typedef T baseT; typedef typename TypeInfo<T>::bottomT bottomT;};template<typename T>class TypeInfo<T&> {public: enum { IsPtrT = 0, IsRefT = 1, IsArrayT = 0 }; enum { Dim = 0 }; typedef T baseT; typedef typename TypeInfo<T>::bottomT bottomT;};template<typename T, size_t N>class TypeInfo <T[N]> {public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 1 }; enum { Dim = 1 + TypeInfo<T>::Dim }; typedef T baseT; typedef typename TypeInfo<T>::bottomT bottomT;};template<typename T, size_t N>class TypeInfo <T(*)[N]> {public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 1 }; enum { Dim = 2 + TypeInfo<T>::Dim }; typedef T baseT; typedef typename TypeInfo<T>::bottomT bottomT;};template<typename T>class TypeInfo <std::vector<T> > {public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 1 }; enum { Dim = 1 + TypeInfo<T>::Dim }; typedef T baseT; typedef typename TypeInfo<T>::bottomT bottomT;};template<typename T>size_t dims(T& a){ return TypeInfo<T>::Dim;}int main(){ TypeInfo<int** >::bottomT x = 100; typedef int* arrayType[100]; TypeInfo< arrayType >::bottomT y = 200; cout << x << " " << y << endl; cout << TypeInfo<int[3]>::Dim << endl; cout << TypeInfo<int[3][4]>::Dim << endl; int array1[5][6]; int array2[5][6][7]; vector<int (*)[6][7]> array3; cout << dims(array1) << endl; cout << dims(array2) << endl; cout << dims(array3) << endl; cout << TypeInfo<vector<int[3][4]> >::Dim << endl; cout << TypeInfo<vector<vector<int[3][4]> > >::Dim << endl;}
阅读全文
0 0
- 类模板以及其中的traits技术和type classification技术
- 模板元中的类型分类技术(type classification)
- C++模板编程中的Traits技术
- C++模板编程中的Traits技术
- STL中的traits技术
- 类型分类技术(type classification)
- traits:Traits技术初探
- traits:Traits技术初探
- traits:Traits技术初探
- traits:Traits技术初探
- traits:Traits技术初探
- traits:Traits技术初探
- Traits技术
- Traits技术
- Traits 技术
- Traits技术
- C++ 模板类型萃取技术 traits
- 【C++】traits技术与模板元编程
- networking常用命令
- 为laravel5.1生产环境linux从源代码安装PHP
- Android 4.4 Graphic 图形架构
- 我的第一篇博客
- Java代理
- 类模板以及其中的traits技术和type classification技术
- poi导入Excel,兼容03/07版本
- laravel下的团队开发
- laravel重要概念和知识点
- PHP的模板引擎这点事儿
- Hadoop 资源调度架构和实现
- laravel, Composer和autoloading
- struts2前台后台逻辑串联
- PHPStorm/webstorm tips