这几天用template的郁闷和自己的无知(2)

来源:互联网 发布:幼儿园网络监控方案 编辑:程序博客网 时间:2024/05/15 07:44

 3. C++ Type traits

 

一直比较奇怪这个是干什么的,现在总算略知皮毛。现在就读陈崴先生翻译的 和 John Maddock and Steve Cleary 的 C++ Type traits 做点笔记。

 

“总有一些时候,泛型不够好 ─ 有时候是因为不同的型别差距过大,难以产生一致的泛化实作版本。”

也就是在这种时候,我们要对泛型做一些缝缝补补的工作。

 

Traits 就是 “把一系列与型别相关的性质包裹於单一 class 之内”

 

“所谓特性(trait)指的是,举个例子,某型别是否为一个 pointer,或是一个 reference?某型别是否拥有一个 trivial constructor,或是拥有一个 const 修饰词? 这些 type-traits classes 共同享有一致性的设计:每一个 class 都有一个 member value,那是一个编译期常数,如果某型别拥有某种特性,此一常数的值就是 true,否则就是 false。”

 

Traits实现这个member value的时候常常用到前面折腾了我一阵的特化,先提供一个标准的主板本的template class ,然后针对那些不好处理的做特化版本。

 

C++ boost中的type-traits library 是Traits最典型的例子

 

最简单的例子

 

is_void<T> 有一个 member value,如果 T 是 void,它就是 true。

template <typename T> struct is_void{ static const bool value = false; };template <> struct is_void<void>{ static const bool value = true; };
这里是利用全特化来设计的,内部没有实际用到模板参数,看上去有点傻,呵呵。
还有一个例子是class boost::is_pointer<T>
template <typename T> struct is_pointer { static const bool value = false; };template <typename T> struct is_pointer<T*> { static const bool value = true; };
再摘录一段有用的:

偏特化的语法带了点不可思议的味道,而且一谈到它很容易就耗掉一整篇文章。就像全特化的情形一样,为了针对某个 class 写出一个偏特化版本,你首先必须宣告 template 主版本。偏特化版本在 class 名称之後多出一个 <┅> ,其中内含偏特化叁数;这些叁数定义出「将被系结於偏特化版」的某些型别。究竟什麽叁数会(或说能够)出现於偏特化版本之中,规则颇为曲折,以下是一个简略的规则。如果你能够以此型式合法写出两个多载化函式:

void foo(T);void foo(U);

那麽你就能够以此型式写出一个偏特化版本:

template <typename T>class c{ /*details*/ };template <typename T>class c<U>{ /*details*/ };

这个简则并非绝对成立,但它非常简单,足以让你牢牢记住并足够接近精确的规则。

原创粉丝点击