简介
C++11,也称为C++0x。为目前C++编程语言的最新正式标准(ISO/IEC 14882:2011)。它将取代第二版标准ISO/IEC 14882:2003(第一版ISO/IEC 14882:1998公开于1998年,第二版于2003年更新,分别通称C++98以及C++03,两者差异很小)。C++11包含了核心语言的新机能,并且拓展C++标准程序库,并且加入了大部分的C++ Technical Report 1程序库(数学上的特殊函数除外)。C++ 标准委员会计划在2010年8月之前完成对最终委员会草案的投票,以及于2011年3月3召开的标准会议完成国际标准的最终草案。最终于2011年8月12日公布,并于2011年9月出版。2012年2月28日的国际标准草案(N3376)是最接近于现行标准的草案(编辑上的修正)。此次标准为13年第一次重大修正。
[1]
编辑本段版本变更
1.对C++核心语言的扩充
2.核心语言运行期的强化(右值引用和 move 语义;泛化的常数表达式;对POD定义的修正)
3.核心语言建构期表现的加强(外部模板)
4.核心语言使用性的加强(初始化列表;统一的初始化;类型推导[auto关键字];以范围为基础的 for 循环;Lambda函数与表示法;另一种的函数语法;对象构建的改良;显式虚函数重载;空指针;强类型枚举;角括号;显式类型转换;模板的别名;无限制的unions)
5.核心语言能力的提升(变长参数模板;新的字符串字面值;用户自定义的字面值;多任务存储器模型;thread-local的存储期限;使用或禁用对象的默认函数;long long int 类型;静态assertion;允许sizeof运算符作用在类型的数据成员上,无需明确的对象;)
6.C++标准程序库的变更(标准库组件的升级;线程支持;多元组类型;散列表;正则表达式;通用智能指针;可扩展的随机数功能;包装引用;多态函数对象包装器;用于元编程的类型属性;用于计算函数对象返回类型的统一方法)
编辑本段现状
每个标准的发布都需要一段时间的普及。包括技术图书,编译器支持。截至目前(2012-8-14)。距离标准发布接近了一年。目前美国已经更新了大部分著名C++图书(如:C++ Primer(第五版);C++ Primer Plus(第六版)注:目前primer暂无中文版;Plus于6月22日已经发布中文版)。VS2012,G++,Clang也都逐步添加对C++11的支持。图为迄今支持情况。
编辑本段示例
类型推导与auto关键字
在标准C/C++,使用变量必须明确的指出其类型(强类型)。然而随着模板类型的出现以及模版元编程的技巧,指定类型,特别是函数定义明确的指定返回类型,就不容易表示。在这样的情况下,将中间结果存储与变量是一件困难的事情,可能会需要知道特定的元编程程序库的内部情况。
C++11提供了两种方法缓解上述所遇到的困难。首先被有明确初始化的变量可以使用auto关键字。这会依据该初始化式的具体类型产生变量。示例:
auto someStrangeCallableType = boost::bind(&SomeFunction, _2, _1, someObject);
|
auto otherVariable =5;
|
someStrangeCallableType 的类型是模版函数 boost::bind对特定引数返回的类型,作为编译器语义分析的一部分,这个类型能够简单地被编译器决定,但用户要通过查看来判断类型就不是一件容易的事情。
otherVariable 的类型同样也是明确定义的,但用户很容易就能判断。它是个int(默认整数类型)。
除此之外,C++11还定义了 decltype 能够被用来在编译器决定一个表达式的类型。举例:
int someInt;
decltype(someInt) otherIntegerVariable =5;
|
decltype 和 auto 一起使用会更为有用,因为 auto 变量的类型只有编译器知道。然而 decltype 对于那些大量运用运算符重载和特化的类型的代码的表示也非常有用。
auto 对于减少冗赘的代码也很有用。举例而言,程序员不用写像下面这样:
for(vector<int>::const_iterator itr = 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++已经有了强制编译器在特定位置开始实例化的语法:
templateclass 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,或是其他符合范围概念的对象。
[1]
int my_array[5]={1, 2, 3, 4, 5};
for(int& x : my_array)
{
x *=2;
}
|
编辑本段编译支持
Feature
|
VS11
|
g++ 4.7
|
Clang 3.1
|
---|---|---|---|
auto
|
Yes
|
Yes
|
Yes
|
decltype
|
Yes
|
Yes
|
Yes
|
Rvalue references and move semantics
|
Yes
|
Yes
|
Yes
|
Lambda expressions
|
Yes
|
Yes
|
Yes
|
nullptr
|
Yes
|
Yes
|
Yes
|
static_assert
|
Yes
|
Yes
|
Yes
|
Range based for loop
|
Yes
|
Yes
|
Yes
|
Trailing return type in functions
|
Yes
|
Yes
|
Yes
|
final method keyword
|
Yes
|
Yes
|
Yes
|
override method keyword
|
Yes
|
Yes
|
Yes
|
Strongly typed enums
|
Yes
|
Yes
|
Yes
|
Forward declared enums
|
Yes
|
Yes
|
Yes
|
extern templates
|
Yes
|
Yes
|
Yes
|
>> for nested templates
|
Yes
|
Yes
|
Yes
|
Local and unnamed types as template arguments
|
Yes
|
Yes
|
Yes
|
Variadic macros
|
Yes
|
Yes
|
Yes
|
New built-in types
|
Partial
|
Yes
|
Yes
|
Initializer lists
|
No
|
Yes
|
Yes
|
explicit type conversion operators
|
No
|
Yes
|
Yes
|
Inline namespaces
|
No
|
Yes
|
Yes
|
sizeof on non-static data members without an instance
|
No
|
Yes
|
Yes
|
Changed restrictions on union members
|
No
|
Yes
|
Yes
|
Raw string literals
|
No
|
Yes
|
Yes
|
User defined literals
|
No
|
Yes
|
Yes
|
Encoding support in literals
|
No
|
Yes
|
Yes
|
Arbitrary expressions in template deduction contexts
|
No
|
Yes
|
Yes
|
Defaulted methods
|
No
|
Yes
|
Yes
|
Deleted methods
|
No
|
Yes
|
Yes
|
Non-static data member initializers
|
No
|
Yes
|
Yes
|
Variadic templates
|
No
|
Yes
|
Yes
|
Default template arguments in function templates
|
No
|
Yes
|
Yes
|
Template aliases
|
No
|
Yes
|
Yes
|
Forwarding constructors
|
No
|
Yes
|
Yes
|
noexcept
|
No
|
Yes
|
Yes
|
constexpr
|
No
|
Yes
|
Yes
|
Alignment support
|
Partial
|
No
|
Yes
|
Rvalue references for *this
|
No
|
No
|
Yes
|
C99 compatibility
|
Partial
|
Partial
|
Partial
|
Thread local storage
|
Partial
|
Partial
|
No
|
Inheriting constructors
|
No
|
No
|
No
|
Generalized attributes
|
No
|
No
|
No
|
通过对比可以发现,Clang在大多数C++11功能实现上处于领先地位,而Visual Studio则稍显落后。当然,这三个编译器都有着不错的子集适用于跨平台开发。
你可以使用类型推断、移动语义、右值引用、nullptr,static_assert,range-based参考对比。同时你还可以使用最终和重写关键字来进行友好的控制。此外,你还可以通过Enums(例举)强类型和提前声明,这里有几个改进后的模板包括extern keyword。
遗憾的是,Visual Studio并不支持较多请求的可变参数模板。另一方面,可变参数宏在这三款编译器中只支持C99标准。继承构造函数和广义属性这些特性并不是在任何地方都能获得支持。本地线程存储是是支持情况最好的一部分(通过非关键字标准)。
[2]