自己的无知(2)"/>
这几天用template的郁闷和自己的无知(2)
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*/ };这个简则并非绝对成立,但它非常简单,足以让你牢牢记住并足够接近精确的规则。
更多推荐
这几天用template的郁闷和自己的无知(2)
发布评论