此文档整理c++11中新特性.
语言:
- Variadic Templates
- move Semantics
- auto
- auto和decltype的区别与联系
- range base for
- Initializer list
- Lambdas
- type_traits
- Unordered Containers
- forward_list
- array
- explicit
- tuple
- Con-currency
- RegEx
Initializer list
1 | int values[]{1,2,3}; |
当编译器看到{t1,t2,…,tn}便做出一个initializer_list
却不能给予数个T参数然后以为它们会被自动转为一个initializer_list<T>传入.
对于vector<string>cities{“hello”,”hi”}; {“hello”,”hi”}形成了一个initializer_list<string>,背后有个array<string,2>,调用vector<string> ctor时编译器找到一个vector<string> ctor接受initializer_list<string>.所有容器都有这样的ctor.
complext<double> c{4.0, 3.0}; 这形成一个initializer_list<string>,背后有个array<double,2>.调用complext<double> ctor时该array内的2个元素被分解传给ctor.因为complex<double>并无任何ctor接受initializer_list.
initializer_list的使用
在函数中使用initializer_list传递不定个参数
1 | void print(initializer_list<int> vals) { |
在类中使用initializer_list
1 | class P { |
1 | void test2() { |
在标准库容器和算法中使用initializer_list
1 | vector<int> v1{11, 22, 454, 33}; |
initializer_list的实现
1 | template<class _E> |
explicit
对于仅有单一实参(也可能是有n(n>=2)个参数,但是n-1个参数都有默认实参)的构造函数,指定expliciit表示不允许隐式转换.
对于多个实参的构造函数,指定explicit表示不允许进行隐式转换.
如果没有指定explicit,那么对于多个实参的构造函数也可以进行隐式转换.
1 | class P { |
运行结果:
1 | a=1 b=2 c=3 |
Alias Template(template typedef)
与模板模板参数相关.
1 | template<typename T> |
type Alias
1 | typedef void(*func)(int, int); // func是一个返回值为void,两个int参数的函数指针类型 |
using
using的三种用法
using-directives
1 | using namespace std; |
using-declarations
1 | class Derived:public Base{ |
type alias and alias template
1 | template<typename> |
1 | // type alias used to hide a template parameter |
noexcept
final
final有两种用法:
- 修饰class,禁止类被继承
- 修饰virtual function,禁止virtual function被重写
decltype
decltype可以找出一个表达式的类型.
decltype有三种用法:
声明一个type作为返回类型
1
2
3
4template<typename T1, typename T2>
auto add(T1 x, T2 y) -> decltype(x + y) {
return x + y;
}在metaprogramming中使用
取一个表达式的类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14template<typename T>
void test_decltype(T obj) {
typedef typename decltype(obj)::iterator iType; // 相当于typedef typename T::iterator iType
iType it = obj.begin();
if (it != obj.end()) {
cout << "not empty container" << endl;
} else {
cout << "empty container" << endl;
}
decltype(obj) anoObj(obj);
cout << "anoObj.size(): " << anoObj.size() << endl;
cout << endl;
}面对lambda,往往只有object,没有type,要获得其类型就需要借助于decltype.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class Person {
public:
Person(string _firstName, string _lastName) : fname(_firstName), lname(_lastName){}
string firstName() const { return fname; }
string lastName() const { return lname; }
private:
string fname;
string lname;
};
auto comp = [](const Person &p1, const Person &p2) {
return p1.lastName() < p2.lastName()
|| (p1.lastName() == p2.lastName() && p1.firstName() < p2.firstName();
};
set<Person, decltype(comp)> coll(comp);lambda