-
例子1
template <typename T> struct my_is_void{ static const boo value = false; }; template <> strcut my_is_void<void>{ static const bool value = true; }; cout << my_is_void<int>::value << endl; cout << my_is_void<void>::value << endl;
上面这个例子就是利用模板偏特化以及类静态变量实现对类型判断是否谓空类型的例子。这个例子只是引自,下面讲2个实用的例子。
-
例子2
template <typename Iterator> void func(Iterator iter){ // 我们想用迭代器的类型定义一个变量该怎么办? *iter var // 这样是不能通过编译的。 } // 转换思路 template <typename Iterator> void func(Iterator iter){ __func(&*iter); } template <typename T> void __func(T* ){ T var; }
-
type_traits
在C++中有的比如int, bool, char等类型没有必要有构造,拷贝构造等函数,我们称之为trivial_default_constructor,trivial_copy_constructor,trivial_assignment_operator,trivial_destructor,我们称之为POD_type。反之称之为no_POD_type。这个定义可能不严谨,但不是今天这篇文的重点。在SGI STL底层的有这样一个函数。目的是析构[ first, last )的元素
template <typename ForwardIterator> inline void destory(ForwardIterator first, ForwardIterator last) { if (is_POD_type(*first)) //....是int等类型,不需要析构。 if (is_no_POD_type(*first)) for (; first != last; first++) first->~(*first)() // 调用析构函数,(*first)不能通过编译。 }
但是怎么表现is_POD_type和is_no_POD_type这2个意思了?这个时候我们可以用内嵌型别和偏特化来实现。
// 标明类型 struct _true_type { }; struct _false_type { }; // 用于萃取是否为POD_type template <typename T> struct _type_traits{ typedef _false_type has_trivial_default_constructor; typedef _false_type has_trivial_copy_constructor; typedef _false_type has_trivial_assignment_operator; typedef _false_type has_trivial_destructor; typedef _false_type is_POD_type; }; // char偏特化 template<> struct _type_traits<char> { typedef _true_type has_trivial_default_constructor; typedef _true_type has_trivial_copy_constructor; typedef _true_type has_trivial_assignment_operator; typedef _true_type has_trivial_destructor; typedef _true_type is_POD_type; }; // int偏特化 template<> struct _type_traits<int> { typedef _true_type has_trivial_default_constructor; typedef _true_type has_trivial_copy_constructor; typedef _true_type has_trivial_assignment_operator; typedef _true_type has_trivial_destructor; typedef _true_type is_POD_type; }; /* 其他类型类推定义偏特化版本。 */ // 判断元素是否为non trivaial destructor。激活重载决议 template <typename ForwardIterator> inline void destory(ForwardIterator first, ForwardIterator last) { /* 利用_type_traits类嵌型别萃取 */ typedef typename _type_traits<ForwardIterator>::is_POD_type is_POD_type; __destory_aux(first, last, is_POD_type()); } // 元素是trivial destructor, 则什么都不用做 template <typename ForwardIterator> inline void __destory_aux(ForwardIterator first, ForwardIterator last, _true_type) { } // 元素是non trivial destrouctor,调用destroy template <typename ForwardIterator> inline void __destory_aux(ForwardIterator first, ForwardIterator last, _false_type) { for (; first != last; ++first) destory(&*first); } // destroy中调用析构函数 template <typename T> inline void destory(T* pointer) { pointer->~T(); }
迭代器中的iterator_traits
见下一篇文章迭代器。
traits技术
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 在iOS开发过程中, 我们可能会碰到一些系统方法弃用, weak、循环引用、不能执行之类的警告。 有代码洁癖的孩子...
- 所有的编译警告的名称:参见网址:http://fuckingclangwarnings.com注意这篇文章的创建时...