这是CodeProject上的一篇Top Article,地址:http://www.codeproject.com/KB/stl/stl2010.aspx
这只是一篇简单的阅读笔记,不是文章的完整翻译。另外因为vc2010在2008年发布,在c++0x正式标准发布之前,所以vc中的实现与标准描述可能有些不太一致的地方。
Constant Iterators
增加了返回const_iterator的接口
引入这四个新接口的原因是为了配合新加入的auto关键字
The array Class
安全的固定大小数组,所以size方法返回的始终是数组最大容量
The tuple Class
可以容纳2到10个元素的pair
New functions in <algorithm>
新加入的函数有 all_of, any_of, none_of, find_if_not, copy_if, partition_copy
is_partitioned, partition_point, minmax_element, is_sorted, is_sorted_until
is_heap, is_heap_until, move
注意partition_point,作者阅读代码并测试后发现其行为与标准描述的不一致
Random Number generator Classes (<random>)
random库与原始rand相比的优点在于:新的random库生成32位包含正值和负值的伪随机数
Improvements in sets and Unordered Sets
unordere_set用来代替以前非标准的hash_set
unordered_set在插入时间上与set相同,但是在查询时间上要少很多,unordered_set为常数题意,而set为 O(log n)
Improvements in maps and Unordered Maps
unordered_map用来代替以前非标准的hash_map
unordered_map主要用于优化查询速度,插入速度比map要慢
Regular Expressions
Changes in functional, utility headers
The memory header, Enhanced "pointer management classes
这些部分没有具体描述
该作者在CodeProject还有另外一篇文章介绍C++0x的新内容
地址:http://www.codeproject.com/KB/cpp/cpp10.aspx
The auto keyword
类似于动态语言里的var, 不过在c++中auto的实际类型将在编译期进行推导,运行期也不允许改变实际类型
auto关键字的适用场合:
1. When the data-type may change depending on the compiler and / or target-platform
例如用于解决32位机与64位机int长度的差异问题
2. when the data-type is complex to express, or it makes the code clutter
例如用于代替 std::vector<std::string>::iterator这样的长类型,可简写为auto itr = Strings.begin();
3. To assign Lmabdas to a variable
4. To specify Trailling Return types
The decltype keyword
用于获取变量的类型定义
与typeid关键字不同的是,typeid返回type_info结构体,并且要求启用RTTI,而decltype在编译期推导变量的实际类型,可用来声明新的变量,比如:
int nVariable1;
decltype(nVariable1) nVariable2;
注意这两种表示方法的区别:
decltype(SomeFunc) yVar;
decltype(SomeFunc()) yVar;
第一种声明yVar为function-pointer
第二种声明yVar为SomeFunc()函数的返回值类型
因为decltype的求值是在编译期,所以下面两种写法并不会引起程序崩溃,也不会让程序退出
decltype(1/0) Infinite;
decltype(exit(0)) MyExitFunction();
The nullptr keyword
大部分情况下nullptr与NULL宠定义或者integer 0相同,但是,nullptr是一个keyword而不是一个类型,所以不能对nullptr使用sizeof操作符,也不能使用decltype
NULL宏定义与nullptr关键字是不同的entities,NULL is just 0, which is nothing but int.
注意下面的例子:
void fx(int*) {}
void fx(int) {}
int main()
{
fx(nullptr); // 将会调用fx(int*)
fx(NULL); // 将会调用fx(int)
}
the static_assert keyword
编译期断言
Lambda Expressions
Lambda ar like locally-defined functions.
最简单的lambda定义:[]{}; 这个表达式什么也不做。
复杂一点的 bool is_even = [](int n) { return n % 2 == 0; } (41);
Lambda表达式中引用外部参数有[], [=], [&], [var], [&var]及其组合的方式,组合的方式有:
[&,var], [=, &var], [var1, var2], [&var1, &var2], [var1, &var2]
对于传值的参数来说,在Lambda表达式中该值都为const类型,如果想要修改这些参数,就像使用一个普通的函数参数值一样,那么可以对Lambda表达式加上mutable标记,比如:
[=]()mutable->void { x++; }();
Trailling Return types
用于不确定返回类型的函数表达式中,比如:
template<typename FirstType, typename SecondType>
/* UnknownReturnType */ AddThem(FirstType t1, SecondType t2) { return t1 + t2; }
这时可以用Trailling Return type来解决:
template <typename FirstType, typename SecondType>
auto AddThem(FirstType t1, SecondType t2) -> decltype(t1 + t2) { return t1 + t2; }
该模板函数的真实返回类型将在模板被实例化时进行推导,如果decltype(t1+t2)推导不出,则报错
R-value references
可用于对中间临时变量的优化
引入了一个新的概念:Move-constructor,表示把一个对象的内存从老的实例转移到新的实例。比如:
class Simple
{
void* Memory;
public:
Simple() { Memory = nullptr; }
Simple(Simple&&sObj)
{
Memory = sObj.Memory;
sObj.Memory = nullptr;
}
Simple(int nBytes)
{
Memory = new char[nBytes];
}
~Simple()
{
if (Memory != nullptr)
delete []Memory;
}
};
注意,只有在函数返回对象实例,而非对象引用或对象指针时,才有可能使得Move-constructor被调用,编译器也不会提供默认的Move-constructor,如果需要这种优化方法则应该自己定义Move-constructor
同样的还有Move-assignment操作符
void operator=(Simple&& sOther)
{
delete []Memory;
Memory = sOther.Memory;
sOther.Memory = nullptr;
}
Other language features
一些VC8/VC9自己添加了语言增强特性,这部分内容现在已属于C++0x标准
1. Strongly typed enums
如 enum Proority: BYTE { VeryLow = 0, Low, Medium, High, VeryHigh };
enum ByteUnit : unsigned __int64 { Byte = 1, PetaByte = (unsigned __int64)1 << 50 };
对这些enum类型取sizeof时,其长度将为1和8
2. Right angle brackets
简单来说,vector<list<int>> ListVector; 这样写不会报错了 (注意后两个>>之间不再需要空格 )
3. Extern templates