月度归档:2014年03月

扒一扒gcc 4.4下可用的c++0x特性

上帝说要有光,于是就有了光;老大说要有C0x文档,于是就有了这篇文章。
一切按http://gcc.gnu.org/gcc-4.4/cxx0x_status.html官方文档中支持的特性来。

1. 右值
1). 右值基本使用
其实基本不用改变神马,因为支持这些特性的gcc库头文件中都有了对应的右值版本,主要有两种情况。
a) 当参数是右值时,支持的化自动会调用对应的版本来执行。例如 string a = func();
b) 当参数是左值时,用move转成右值再调用。例如 string a = “cxxfsdf”; string b = move(a);
C++类中支持右值的版本,一般出现在类似与复制/赋值构造函数,插入函数(push_back右值版本内部调用emplace_back)等可能与临时对象交互的场景。
2).  4.4上的右值支持还有些蹊跷
文档上说gcc4.4支持右值,但事实上还是有些不一样。

以上代码,在两套环境中都能正确编译通过。来了个简单的benchmark(以上代码b,c各自循环100W次)。在gcc 4.8下,string和vector的右值版本是能明显看到效率提升的。但在gcc 4.4.7下,string却没差别。打开4.4.7的/usr/include/c++/4.4.7/bits/basic_string.h,没有看到赋值/复制构造函数的右值版本,而4.8的对应的basic_string.h中却有对应的右值版本。继续对照4.4.7的/usr/include/c++/4.4.7/bits/stl_vector.h,不言自明。

2.  变参模版
直接上最近项目中用的代码,packString(1213, 11.1, “12121”)。这个特性可以组合出很多简化代码的例子。

3.  统一初始化列表
这个没啥好说的,所有类型都能用{}来初始化,并产生相同的结果。

4.  静态断言
编译期(非预编译期)判断,在这个特性之前,框架通过内核宏来模拟编译期断言,现在方便多了。

5. 自动推导
1). auto
初始化自动推导类型:以前咱们必须这样std::vector::iterator iter = xxx.begin();现在咱们可以这样auto iter = xxx.begin();语言级别上更智能了,代码可以更精简。
2). decltype
根据表达式推导类型,模版中更强大:decltype(t) b; decltype(a + b + c) dd;

6. 右尖括号
这个算一个小特性,之前两个右尖括号在一起的时候编译会报错,通常要空一个空格,现在ok了。
set<pair<uint32_t,uint32_t> > xx; set<pair<uint32_t,uint32_t>> yy;

7. sizeof扩展
sizeof可以用在类成员身上了。struct to { int d;}; sizeof(to::d);

8. 模版函数支持默认模板参数
之前模版类支持默认模版参数,现在模版函数也能支持到。template <typename T=int> void fc() {};

9. 强类型枚举
虽然使用枚举值的地方同城也可以用整型等来代替,但是这个特性可以更加方便的限定参数,避免出错。

10. 显式启用或禁用特定的成员函数
简单说就是通过default和delete两个关键字来指明启用或禁用哪些成员函数。之前防止类拷贝喜欢继承boost中的noncopyable类,现在更简洁指明关键字就o拉。

11. 并发相关
坑爹的4.4的原子操作头文件是cstdatomic,4.7之后又是标准的atomic头文件了。其他的如thread等都有相应的头文件。这类特性对后台开发最有吸引力,但是在4.4中的支持力度没有看到详细的说明,暂不敢贸然使用。