长期以来,KlayGE的很多代码都依赖于boost。(这里有个列表)。上次我提到过,随着C++11编译器和库的普及,boost中的很多东西都可以用C++11来代替。我这两天正试着在KFL中做这件事情,以下的过程中总结的经验和教训。当然,这里只涉及到KlayGE使用的boost组件,没使用到的我没做测试。所有这些替换都保证了可以通过宏来切换回boost的实现。
可以直接替换
标记了*的表示需要编译才能使用的boost组件。下同。
Array
Chrono *
Foreach
Regex *
System *
Static Assert
Type Traits
Typeof
Unordered
这些boost组件都可以直接用C++11的相应组件替换掉。Foreach、Static Assert和Typeof是语言核心提供的,需要写个宏来统 ...
时间过得真快,离上一次讨论编译期字符串Hash已经差不多2年了。上次的尝试失败了,只能产生优化期常量,没有做到编译期常量的效果。现在有了C++11,情况会不会有所改变呢?
constexpr
上次的帖子中,在回复mtlung的时候,我提到了C++0x的constexpr可能会成为救星。现在C++11的标准出来了,GCC 4.6+和Clang 3.1+也开始支持constexpr了。首先尝试宏的做法,代码和上次几乎相同:
constexpr inline size_t HASH_FUNCTION(size_t seed, char ch)
{
return seed ^ (ch + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
#define HASH_RECURSE_00(seed, str) (*(str + 1) == 0 ? HASH_FUNCTION((seed), *(str)) : HASH_RECUR ...
上次对各编译器对C++11的支持比较之后,很多观众提议加入Intel C++ Compiler(ICC)和Clang。这次修订还加入了在VC11 Nov 12 CTP中对C++11的提升。上回表中的Yes/No标识也被我改成了写明支持一个feature的最低版本号,feature的顺序也调整了一下。为了方便查询,还加入了Proposal的链接。
C++11 Core Language Features
Language Feature
Proposal
MSVC
GCC
ICC
Clang
替代方案
Rvalue references
N2118
10.0
4.3
12.0
2.9
Boost.Move
Rvalue references for *this
N2439
No
No
No
2.9
Initialization of class objects by rvalues
N1610
9.0
4.3
11.1
2.9
Non-static data membe ...
昨天比较完各编译器对C++11的支持,决定一蹴而就,继续引入几个不影响接口的C++11语言核心特性。于是选了type traits、static assert、range-based for和decltype。前三个都好办,用个宏包起来,在不支持C++11的编译器上切换回Boost的实现。只有decltype是需要特别注意的。
BOOST_TYPEOF也能实现类似decltype的功能,比如有一个vector<int> v,typedef BOOST_TYPEOF(v) VType;,那么VType就是vector<int>了。但如果v是vector<int>&,BOOST_TYPEOF(v)得到的是vector<int>,而decltype(v)得到的是vector<int>&。如果要接着把VType用作别的用途,比如通过VType::reference得到int&,这两者就会有 ...
在KlayGE首次引入C++11特性之后,我顺便调研了一下个主流编译器对C++11的支持度,以便在下个版本中加入更多的C++11元素。这里还列出了在不支持的时候,可以采用的替代方案。主要参考了C++11 Features in Visual C++ 11,Status of Experimental C++0x Support in GCC 4.6,Status of Experimental C++0x Support in GCC 4.7,Boost。
C++11 Core Language Features
VC 10
VC 11
GCC 4.6
GCC 4.7
替代方案
Rvalue references
Yes
Yes
Yes
Yes
Boost.Move
Rvalue references for *this
No
No
No
No
Non-static data member initializers
No
No
No
Yes
Variadic templates
No
No
Yes
Y ...
在KlayGE开发版中,C++11的部分特性第一次被采用。目前用到的有两处,nullptr和强类型enum。所有这些C++11 only的代码都被放入#ifdef /#endif,同时提供了非C++11的替代实现。
nullptr
nullptr是C++11定义的强类型空指针,用来取代NULL。强类型的保证减少了bug的可能性,相关的介绍很容易找到,这里就不累赘了。在不支持C++11的编译器上,也可以实现一个同样功能的nullptr:
const class nullptr_t
{
public:
template
operator T*() const
{
return reinterpret_cast(0);
}
template
operator T C::*() const
{
return reinterpret_cast(0);
}
private:
void operator&() const;
} nullptr = {};
强类型enum ...