c++11的示例
C++ 11 标准废除了旧的 C++ 98 标准中 auto 的意思(自动变量类型),改成了自动类型推导的意思。
在标准C/C++,使用变量必须明确的指出其类型(强类型)。然而随着模板类型的出现以及模版元编程的技巧,指定类型,特别是函数定义明确的指定返回类型,就不容易表示。在这样的情况下,将中间结果存储与变量是一件困难的事情,可能会需要知道特定的元编程程序库的内部情况。
C++11提供了两种方法缓解上述所遇到的困难。首先被有明确初始化的变量可以使用auto关键字。这会依据该初始化式的具体类型产生变量。示例: auto otherVariable = 5;//otherVariable被按照int型来编译otherVariable 的类是明确定义的。因为5的类型是int,所以编译器按照“int otherVariable =5;”来编译。 auto someStrangeCallableType = boost::bind(&SomeFunction,_2,_1,someObject);someStrangeCallableType 的类型是模版函数 boost::bind对特定引数返回的类型,作为编译器语义分析的一部分,这个类型能够简单地被编译器决定,但用户要通过查看来判断类型就不是一件容易的事情。
除此之外,C++11还定义了 decltype 能够被用来在编译器决定一个表达式的类型。举例: int someInt;decltype(someInt) otherIntegerVariable = 5;decltype 和 auto 一起使用会更为有用,因为 auto 变量的类型只有编译器知道。然而 decltype 对于那些大量运用运算符重载和特化的类型的代码的表示也非常有用。
auto 对于减少冗赘的代码也很有用。举例而言,程序员不用写像下面这样: for(vector<int>::const_iteratoritr=myvec.begin(); itr!=myvec.end(); ++itr)可以使用auto简化为: for(auto itr = myvec.begin(); itr != myvec.end(); ++itr)这项差异随着程序员开始嵌套容器而更为显著,虽然在这种情况下 typedef 是一个减少代码的好方法。
decltype 所表示的类型可以和 auto 推导出来的不同。 #include<vector>int main(){ const std::vector<int>v(1); auto a = v[0];//a为int类型 decltype(v[0]) b = 0;//b为const int&类型,即std::vector<int>::operator[](size_type)const的返回类型 auto c = 0;//c为int类型 auto d = c;//d为int类型 decltype(c) e;//e为int类型,c实体的类型 decltype((c)) f = e;//f为int&类型,因为(c)是左值 decltype(0) g;//g为int类型,因为0是右值 return 0;} 在标准C++中,只要在编译单元内遇到被完整定义的模板,编译器都必须将其实例化(instantiate)。这会大大增加编译时间,特别是模板在许多编译单元内使用相同的参数实例化。看起来没有办法告诉C++不要引发模板的实例化。
C++11将会引入外部模板这一概念。C++已经有了强制编译器在特定位置开始实例化的语法:
template class std::vector<MyClass>;
而C++所缺乏的是阻止编译器在某个编译单元内实例化模板的能力。C++11将简单地扩充前文语法如下:
extern template class std::vector<MyClass>;
这样就告诉编译器不要在该编译单元内将该模板实例化。
以范围为基础的for循环
Boost C++ 定义了许多范围 (range) 的概念。范围表现有如受控制的串行 (list),持有容器中的两点。有序容器是范围概念的超集 (superset),有序容器中的两个迭代器 (iterator) 也能定义一个范围。这些概念以及操作的算法,将被并入 C++11 标准程序库。不过 C++11 将会以语言层次的支持来提供范围概念的效用。
for 语句将允许简单的范围迭代:第一部分定义被用来做范围迭代的变量,就像被声明在一般for循环的变量一样,其作用域仅只于循环的范围。而在:之后的第二区块,代表将被迭代的范围。这样一来,就有了能够允许C-style数组被转换成范围概念的概念图。这可以是std::vector,或是其他符合范围概念的对象。 int my_array[5]={1, 2, 3, 4, 5};for(int& x : my_array){x *= 2;}编译器支持 功能 VS2011 VS2013g++ 4.7 Clang 3.1 auto关键字 Yes Yes YesYesdecltype关键字Yes Yes YesYes右值引用(Rvalue references)与移动语义(move semantics)Yes Yes YesYesLambda表达式 Yes Yes YesYesnullptr关键字Yes Yes YesYes静态断言(static_assert)关键字 Yes Yes YesYes基于范围的循环(Range based for loop)语法 Yes Yes YesYes函数返回类型后置(Trailing return type in functions)语法Yes Yes YesYesfinal关键字Yes Yes YesYesoverride关键字Yes Yes YesYes强类型枚举(Strongly typed enums)Yes Yes YesYes前置枚举声明(Forward declared enums) Yes Yes YesYes外部模板(extern templates)Yes Yes YesYes模板右尖括号嵌套(>> for nested templates)Yes Yes YesYesLocal and unnamed types as template argumentsYes Yes YesYes变参宏(Variadic macros)Yes Yes YesYes新内建类型(New built-in types)Partial(部分)?YesYesInitializer_lists容器No?YesYes显式类型转换运算符(explicit type conversion operators)NoYes YesYes内联命名空间(Inline namespaces)No?YesYessizeof用在没实例时的非静态成员
(sizeof on non-static data members without an instance) No?YesYes改变union成员限制(Changed restrictions on union members)No?YesYesRaw string literals NoYesYesYesUser defined literals No?YesYesEncoding support in literals No?YesYesArbitrary expressions in template deduction contexts No?YesYes默认方法(Defaulted methods) NoYes(有条件支持) YesYes删除方法(Deleted methods) NoYes(有条件支持) YesYes非静态成员初始化(Non-static data member initializers) No?YesYes变参模板(Variadic templates)No?YesYes函数模板中的默认模板参数
(Default template arguments in function templates) No?YesYes模板别名(Template aliases)No?YesYes前置构造函数(Forwarding constructors)No?YesYesnoexcept关键字No?YesYesconstexpr关键字 No?YesYesAlignment 支持 Partial(部分)Partial(部分)YesYes*this的右值引用No?NoYesC99兼容性(C99compatibility)Partial(部分)Partial(部分)Partial(部分)Partial(部分)线程本地存储(Thread local storage)Partial(部分)Partial(部分)Partial(部分) 构造函数继承(Inheriting constructors)No?NoNoGeneralized attributes No?NoNo通过对比可以发现,Clang在大多数C++11功能实现上处于领先地位,而Visual Studio则稍显落后。当然,这三个编译器都有着不错的子集适用于跨平台开发。( 注:GCC4.8.1已完全支持C++11,Clang 3.3 也完全支持了C++11。最新版本的Linux 发行版(RHEL 7,CentOS 7,Ubuntu 14.06,都自带了完全支持C++11的编译器)
你可以使用类型推断、移动语义、右值引用、nullptr,static_assert,range-based参考对比。同时你还可以使用最终和重写关键字来进行友好的控制。此外,你还可以通过Enums(例举)强类型和提前声明,这里有几个改进后的模板包括extern keyword。
遗憾的是,Visual Studio并不支持较多请求的可变参数模板。另一方面,可变参数宏在这三款编译器中只支持C99标准。继承构造函数和广义属性这些特性并不是在任何地方都能获得支持。本地线程存储是是支持情况最好的一部分(通过非关键字标准)。
下面给出在msdn中列举的对C++功能的支持