C++11 - KlayGE游戏引擎 Skip to content

Archive

Tag: C++11
继上一篇提到了把编译器要求升到了vc11/g++ 4.6/clang 3.4之后,develop分支又做出了一些改进。终于,我们完成了现阶段的C++11化改进。 constexpr vc14开始支持constexpr,所以可以用它来实现编译期字符串hash。以后还会进一步增加constexpr的使用,改善执行性能。在KFL里定义了一个宏KLAYGE_CONSTEXPR,在支持的时候是constexpr,否则定义为空。 emplace,move map里插入元素,原先的做法是insert(make_pair(key, value))。这么做代码比较长,在C++11里有了emplace,可以用emplace(key, value)来代替原来的写法。而且STL的实现里一般用了move semantic把key和value直接移入map,不用拷贝。如果原先已经有构造好了的pair,那么用insert和 ...
多年前我写过编译期字符串Hash和再探编译期字符串Hash两篇博文,分别证明了C++98下无法实现编译期的字符串hash,以及如何在C++11下用constexpr实现。过了这么多年,原有的实现在Clang上出现了严重的编译性能下降,需要一些修改才能顺利编译。而vc14也开始支持constexpr了,经过实验,发现问题仍很严重。所以这里不得不再次试着改进编译期字符串hash的方法。 旧方法回顾 上次的实现用了constexpr配合模板嵌套,实现了一个初步的编译期计算字符串hash的方法。 constexpr size_t _Hash(const char (&str)[1]) { return *str + 0x9e3779b9; } template <size_t N> constexpr size_t _Hash(const char (&str)[N]) { ...
One step closer 继拥抱C++11,一步一步来第一篇和第二篇之后,develop分支又经过了一次改进。现在,编译KlayGE所需要的编译器提升到了vc11、g++4.6和clang 3.4。相比上一次的vc10和g++4.3这样刚开始支持C++11的编译器来说,11和4.6基本支持了所有的C++11特性。所以代码里面可以比较自由地使用C++11,而代码更简单。 全部支持的特性 目前vc11、g++ 4.6和clang 3.4都支持的C++11特性如下,远多于vc10、g++ 4.3和clang 3.0这个组合。 语言核心部分 Static assertions (N1720) Multi-declarator auto (N1737) Right angle brackets (N1757) auto-typed variables (N1984) Extern templates (N1987) Rvalue references (N2 ...
在上一篇拥抱C++11,一步一步来里,我制订了一个一步步使用C++11的路线图。KlayGE 4.7去掉了早于vc10、g++ 4.3和clang 3.0的编译器支持,但由于时间关系,还没来得及把它们都支持的C++11特性改为默认开启,仍然用了wrapper层。现在,KlayGE 4.8的开发已经开始,也有足够的时间真正地来执行C++11的计划。目前已经在develop分支里做实现了一部分。 全都支持的特性 整理一下vc10、g++ 4.3和clang 3.0都支持的C++11特性,可以得到一个列表: 语言核心部分 Static assertions (N1720) Right angle brackets (N1757) Extern templates (N1987) auto-typed variables (N1984) Rvalue references (N2118) Declared type of an exp ...
Singleton是一个非常常用的设计模式。几乎所有稍大的程序都会用到它。所以构建一个线程安全,并且高效的singleton很重要。既然要讨论这个主题,我们就先来定义一下我们的需求: Lazy initialization。只有在第一次使用的时候才需要初始化出一个singleton对象。这使得程序不需要考虑过多顺序耦合的情况。同时也避免了启动时初始化太多不知道什么时候才会用到的东西。 线程安全。多个线程有可能同时调用singleton。如果只需要单线程,那实在没什么需要讨论的。 高效。因为singleton会被反复调用,如果效率低的话浪费太大了。 通用。适合现有的各种平台,以及未来可能出现的平台。 有了这些需求,我们就可以开始讨论如何构造这么一 ...
KlayGE在2012年就启用了C++11的部分功能。但目前为止所有用到的C++11特性都要求有一个对应的C++98替代品。要么自己实现,要么用Boost的。 随着时间的推移,各个编译器对C++11的支持越来越好。KlayGE支持的所有平台上,都已经有可用的C++11编译器。实际上如果用的编译器是g++或者clang,-std=c++11都是打开的。所以其实只有Windows上的vc9/10还不能很好地支持C++11。 因为vc9已经无法编译boost,留着没啥意义。对于g++ 4.3之前的版本,或者clang 3.0之前的版本,也没什么人用,也没必要留着。这样在KlayGE支持的编译器中,不支持C++11的就剩下vc10。但至少这样就能直接使用vc10所支持的C++11特性。 所以我的计划是,在目前的开发版本 ...
boost 1.55.0前两天发布了。长期以来KlayGE中集成的boost源代码是用的都奇数版本号的boost,上一个是1.53,所以这次1.55也要集成进来。 除了用bcp缩减boost的大小之外,由于boost在开发的时候没有考虑WinRT和Android这样的平台,所以每次集成后都需要做一些修改才能让boost通过所有的编译。纵观这次的1.55.0,需要修改的地方比以往的都少得多了。主要原因来自几方面: KlayGE从4.3开始引入C++11。原先需要修改的一些库,比如Chrono、Thread、SmartPtr,都因为不再使用boost的实现而没有去修改。 bjam和Config已经支持vc12,所以不需要自己打补丁。 Endian改用新增的Predef库,已经支持Android和ARM。 Boost.Filesystem已经支持A ...
为了方便维护,各种编译器对C++11的支持比较已经挪到了这里。同时,还加入了ICC 14.0, GCC 4.8.1和Clang 3.3。
经过前两次实验,大部分C++11里有的boost组件都被替换成了C++11中相应的。剩下的还有random库和bind/function/mem_fn/ref/smart_ptr这一组。看来,到了不得不改代码的时候了。 random 在第一次实验里提到过,random虽然在boost和C++11都有,但接口不相同,所以原先我用Boost.Random实现的代码,无法直接替换成C++11的。翻了一遍boost文档,发现现在的boost其实有实现了一套名字和C++11相同的组件,于是我重写了所有用到random的地方,用和C++11兼容的代码,就解决了这个问题。好在random用得不多,改几个地方就都好了。 bind/function/mem_fn/ref/smart_ptr 这几个组件相互依赖,要么全换,要么不换。再加上牵扯面非常广,修改起来几乎都 ...
如果选择了一条路,就要走到底。 前天做了第一次用C++11替代Boost的实验,用C++11的组件替换掉了很多Boost组件。这两天进行了第二次实验,对一些不能整个库替代的组件,做一些局部取代的尝试。同时,因为VC11提供了filesystem,我也测试了一下这个。 可以直接替换 Utility的result_of 唯一的区别在于boost::result_of不能作用于成员变量的指针,但KlayGE没用到这个,所以直接替换了。 稍作修改后可以替换 Filesystem MPL的if_ VC11提供了一个基于Filesystem V2的库,而Boost.Filesystem是V3,接口上有略微不同,但不难处理。这里一个额外好处是,原先在Metro下因为一些API的原因,Boost.Filesystem不能编译成功,所有用 ...