被GCC坑了一把
前几日在重构一个小模块。这个模块的架构本来就很畸形,因为它被要求在不同的设备不同的平台不同的endpoint上运行不同的逻辑,却要做在一个模块里,能给用户一个.a或.lib就可以使用。于是第一版的实现中就有一个变量来区分当前endpoint是哪个,开始还好,后来越来越多的if条件判断endpoint来运行不同的逻辑,代码就丑到令我觉得恶心。于是我就蠢蠢欲动了好久,最后看重构的工作量也不是很大,就跟design这块的小leader打了个招呼开始重构了。
重构方案很简单,原来用变量在运行期决定运行哪块逻辑,改成用C++的模板(特化)在编译期决定。这样有两个主要的好处,一是运行效率必然有所提高,虽然我们根本不在乎这点性能,二是把针对不同endpoint的逻辑分别提取到独立的函数里,代码要整洁多了。当然带来一个最明显的坏处是,原本写在.cpp里的实现方便起见全都移到.h里了,这样只要逻辑有所修改,用户代码也必须得一起重新编译。
总的说来这是利大于弊的好事。不过却在后面试图在Linux上编译时遇到了问题,GCC这货居然不支持成员函数模板特化!新版本我不清楚,至少直到4.7.x版本它仍然不支持,而我们现在仍然用着4.6.x版本。这就让我好一阵纠结。网上搜了一下,确实也发现了一些trick来替代这种手法,最后我只好很无奈地加了个占位的模板类,通过函数重载来解决,这样虽然仍然是在编译期决定调用哪个函数,但代码就不如完全用成员函数模板特化实现的那么干净整洁了。真是被GCC坑了一把。
最后记一下Yiili社区开发的进度。加了几个自定义的错误页面,包括401,403,404,500,503。支持帖子置顶功能。学v2ex把重复内容的回复自动折叠不显示,这个很赞的想法。把about、FAQ、contact页面补上了。还有很重要的一点是,接上了orca.io服务,这样把服务放在国外的机器上,在国内访问的速度也还凑合了,还不用备案,据说他们也有北京BGP机房的线路,但是我从域名CNAME来的IP一直是美国的,不知道是不是要付费的服务才会有,总之感觉很不错。