拯救你的字符串 : 完美救赎之终极奥义
来源:互联网 发布:c语言中的指针 编辑:程序博客网 时间:2024/04/29 23:38
引言:我希望看我的文章的朋友都能够去把我的代码编译一次,这样会发现理解我的文章很轻松。我给的代码都是直接无需修改就可编译并运行的。
前一篇文章http://blog.csdn.net/zy498420/archive/2010/11/10/6000129.aspx说到的种子皮在vc6的不完美适用问题,被彻底的解决了。剃了个头恰好就有思路了。
解决的方法很简单,让前一篇文章所说的bug在且仅在vc6中出现,完美。以毒攻毒,以bug1解决bug2!!
原理:vc6重载决议能力有限,但是却允许右值(临时值)传递给非const引用参数。当然同等条件它的重载决议优先选择带const引用参数(这个规则按标准原本只能用在左值上)的函数。
template <typename D, typename L, typename R, typename C>
inline const _et_private::binary_tree_ref<D, _et_private::binary_tree_ref<D, L, R>, C >
operator + (const _et_private::binary_tree_ref<D, L, R>& lhs, const C& rhs){
return _et_private::binary_tree_ref<D, _et_private::binary_tree_ref<D, L, R>, C > (lhs, rhs);
}
template <typename D, typename L, typename R, typename C>
inline const _et_private::binary_tree_ref<D, C, _et_private::binary_tree_ref<D, L, R> >
operator + (const C& lhs, const _et_private::binary_tree_ref<D, L, R>& rhs){
return _et_private::binary_tree_ref<D, C, _et_private::binary_tree_ref<D, L, R> > (lhs, rhs);
}
瞧,如果C类型也是binary_tree_ref时,编译器就不知道如何2选1了。符合标准的编译器支持对这种情况进行特化来帮助选择,然而vc6对于特化后的函数并没有提升它的重载优先级,而是像二师兄那样傻乎乎的问:又来了一个,3选1,选哪个呢?如果我是观音,我也想踢他了。
解决:把第2个函数的第2个参数去掉const 修饰
template <typename D, typename L, typename R, typename C>
inline const _et_private::binary_tree_ref<D, C, _et_private::binary_tree_ref<D, L, R> >
operator + (const C& lhs, _et_private::binary_tree_ref<D, L, R>& rhs){
return _et_private::binary_tree_ref<D, C, _et_private::binary_tree_ref<D, L, R> > (lhs, rhs);
}
此时C若不是binary_tree_ref,就选择这个新函数(根据标准,把右值(临时值)传递给非const引用参数,编译器会抱错gcc。icc居然只给出警告,不完全算错的原因在于这个可能非法的引用我们永远不去解引用!!所以持有一个可能非法的引用并不会影响程序的运行,这也是这里vc6的“违法”行为居然没有任何坏效果的原因。不过icc是真聪明(真正的分析了inline函数内部的情况发现这个错误不会被触发),gcc是死守规矩的良民,而vc6是纯粹的瞎猫遇到了死老鼠。)。
如果C是binary_tree_ref,根据const永远优先的重载决议原则,vc6自动去选择第一个。
其实选择哪一个函数都是一样的,我们这里需要做的就是帮编译器做出选择。向左转还是向右转,这不是一个问题,只要你勇敢的迈出你的脚步。
好了,上完整代码。种皮和播种2个方法一起贴了上来,供大家参考,种皮和播种2个方法经过了非常多的测试,2者之间效率几乎没有任何区别。没有任何一个编译器能够对其中一种方法能多做一些优化。播种这一招的保留我始终觉得是有意义的。另外我对播种干脆做一个限制:必须放在最左端,不再允许放在第1和第2之间。有些接口,简单些更好用,太通用反而让人郁闷,守规矩总是一件好事。现在胡乱播种有可能编译器会报错!
- 拯救你的字符串 : 完美救赎之终极奥义
- 拯救你的字符串:微有瑕疵的终极救赎
- 拯救你的字符串
- 《肖申克的救赎》是否也拯救了你
- 追妹子的终极奥义
- 拯救你的字符串:精简
- 电脑卡顿的终极奥义
- 网络安全的终极奥义将会是人工智能?
- 拯救你的字符串 :种子的外皮
- 16 - 11 - 16 二叉树(C)生成之--终极奥义--书上没讲的!!
- 我也来开发2048之终极奥义
- 我也来开发2048之终极奥义
- 我也来开发2048之终极奥义
- 我也来开发2048之终极奥义
- 我也来开发2048之终极奥义
- 拯救你的字符串:永远没有终点的补充
- 「巨魔,终极奥义!」
- 如何拯救你的CRM?
- WindowFromPoint
- 烦死了人的团队
- 不要让BIB文件成为加载驱动的拦路虎
- 如何在DOS平台中对PCI卡编程
- oracle xmltype 创建 、插入、更新、查找
- 拯救你的字符串 : 完美救赎之终极奥义
- OpenCV模板匹配的方法识别手势
- 12312321321
- 理解JMeter的聚合报道(Aggregate Report)
- 通过pythong MySQLdb操作mysql数据库的例子
- javascript函数一
- alert 文字换行
- 菜鸟——呵呵
- ANT应用