设为首页 加入收藏

TOP

19.5 explicit_cast(2)
2013-10-07 15:05:58 来源: 作者: 【 】 浏览:68
Tags:19.5 explicit_cast

19.5  explicit_cast(2)

explicit_cast的第一个局部特化版本是explicit_cast<T&>,它的构造函数和隐式转换操作符被声明为私有的,这有效地阻止了explicit_cast被用在任何引用上面。这挺好,但功能太强了,因为我们还想让它能够对基本类型的const引用也能够工作。这正是完全特化闪亮登场的时机。上面的代码中展示的是针对char的特化,另外还有针对其他所有基本类型的特化没有在代码中写出来。 最后,我们还需要对指针类型提供一个局部特化,因为如果没有这个局部特化的话,对于指针类型,编译器就必须在主模板以及针对引用的特化版本之间作出抉择,但有些编译器在这里会报告二义性错误。 于是,借助于这些特化版本,我们就可以分毫不差地得到我们想要的行为。

(注意:如果你想要禁止返回任何指向non-const实例的指针并想为此提供额外的警示,你可以像对引用所做的那样,把针对指针的特化版中的隐式转换操作符也改成私有的,并且进一步为const指针提供特化,也就是说,让explicit_cast<T const*>具有公有的构造函数和转换操作符。一句话,具体由你来定。)

遗憾的是,并非所有常用的编译器都支持局部特化,所以为那些不支持局部特化的编译器提供一个受限版本的explicit_cast是明智之举。你可以通过约束来达到目的。我们采用的方法是在析构函数里面放置constraint_must_be_pod()约束(见1.2.4小节),意思是该模板不能被用在非POD类型上。

程序清单19.7

  1. template <typename T> 
  2. class explicit_cast  
  3. {  
  4.   . . .  
  5. #ifndef ACMELIB_TEMPLATE_PARTIAL_SPECIALIZATION_SUPPORT  
  6.   // 对于那些不支持局部特化的编译器,我们施加constraint_must_be_pod()约束  
  7.   ~explicit_cast()  
  8.   {  
  9.     constraint_must_be_pod(T);  
  10.   }  
  11. #endif /* ! ACMELIB_TEMPLATE_PARTIAL_SPECIALIZATION_SUPPORT */  
  12.   . . .  
  13. };  

就这么多!它并不完美,因为它仍然允许该模板被用在非平凡的POD类型(例如大型结构)上。然而,由于我们已经决定,如果用户"按值"来参数化该模板,那么可能发生的拷贝行为所导致的开销就不是我们的责任了。如果在某些罕见的情况下,编译器不能将结构的中间拷贝优化掉,选择按值传递就是你自己的责任了。约束(记住,这是在编译期)的作用在于:拒绝任何可能具有高昂代价的拷贝操作的非平凡用户自定义类型。

explicit_cast的一个极好的特性是它不但可以被运用到那些提供了explicit_cast操作符的类型上,还能够被运用到那些提供了隐式转换操作符的类型上。这就意味着,不管某个类型是被小心谨慎地编写的还是粗枝大叶地编写的,你都可以编写出针对它们的同样有效的泛型代码,因而explicit_cast就可以成为泛型转换机制的基础,而对于是否转换、转换至什么类型这两个问题,选择权在程序员的手中,而不是编译器。事情本该如此,不是吗?

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇19.7 union_cast(1) 下一篇19.5 explicit_cast(1)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: