C++11中的一些新特性
1. auto关键字
auto关键字可以在编译期自动推导变量的类型,例如:
auto x = 7;
for (auto i = v.begin(); i != v.end(); ++i){
cout << *i << endl;
}
2. for关键字
C++11为for语句提供了类似Java中for或者C#和PHP中foreach的用法:
void f(vector<double> &v){
for (auto &x : v){
cout << x << endl;
}
}
for (const auto x : { 1, 2, 3, 4 }){
cout << x << endl;
}
3. 构造函数和析构函数的控制参数
在C++98中,如果你想禁止一个类的构造函数被调用,你需要将其声明为private成员。C++11提供了一个新特性,你可以再声明构造函数时加上delete来避免构造函数被调用:
class X {
X& operator=(const X&) = delete;
X(const X&) = delete;
~X() = delete;
};
class Y {
Y& operator=(const Y&) = default;
Y(const Y&) = default;
};
例子中default的意思是使用编译器自动合成的构造/西沟函数。
4. 常量表达式
常量表达式可以在很多地方取代宏:
enum Flags { good = 0, fail = 1, bad = 2, eof = 4 };
constexpr int operator|(Flags lhs, Flags rhs){ return Flags(int(f1) | int(f2)); }
void f(Flags x){
switch (x){
case bad: ... break;
case eof: ... break;
case bad | eof: ... break;
default: ... break;
}
}
constexpr int x = bad | eof;
Flags f, constexpr x = bad | f; // error constexpr必须在编译器可以被计算
5. 表达式类型
typedef decltype(x * y) ResultType;
6. 初始化列表
C++11提供了一个新的,统一的初始化列表{}:
vector<double> v = { 1, 2, 3.45 };
list<pair<string, string> languages = {
{ "Nygaard", "Simula" },
{ "Richards", "BCPL" },
{ "Ritchie", "C" },
};
std::initializer_list<T>
void f(initializer_list<int> v){
for (auto x : v){ cout << x << endl; }
}
f({1, 2});
f({});
使用{}初始化时,不会做降低精度的类型转换(narrow)。
int a[3] = { 1, 2, 3 };
7. 委托构造函数
class X {
X(int x){ cout << x << endl; }
X() :X(10){}
X(string s) :X(lexical_cast<int>(s)){}
};
8. 类内初始化
class X {
int a = 7;
};
9. 继承构造函数
struct B {
B(){}
};
struct D : B {
using B:B;
};
10. 编译期断言
static_assert(expression, string)
11. 空指针
nullpter
12. 返回值后置声明
用于无法确定函数返回值类型的场景,不再手动指定返回值类型,而是让编译器自动推导出类型:
template<class T, class U>
auto mul(T x, U y) -> decltype(x * y){
return x * y;
}
13. 模板别名
template<N>
using int_exact = typename int_exact_traits<N>::type;
using P = [](double) -> void;
14. 可变参数模板
template<typename T, typename... Args>
void printf(const char *s, T value, Args... args){
while (s && *s){
if (*s == '%' && *++s != '%'){
cout << value;
return printf(++s, args...);
}
cout << *s++;
}
throw runtime error("extra arguments");
}
15. 右指引用
右值是在计算表达式过程中产生的非持久(临时)对象。
X &&t = f();
T tmp = move(a);
16. 原始字符串
string s = R"(\w\\\w)";
17. 自定义字面值
constexpr complex<double> operator "" i(long double d){
return {0,d};
}
auto z = 2 + 1i;
string operator""s(const char *p, size_n){
return string (p, n);
}
f("Hello\n"s);
18. 语句块属性
void f [[noreturn]] (){ throw "error"; }
for [[omp::parallel()]] (int i = 0; i < v.size(); ++i){ ... }
19. lambda表达式
vector<int> v = { 50, -10, 20, -30 };
sort(v.begin(), v.end(), [](int a, int b){ return abs(a) < abs(b); });
int count = 0;
int v[10];
generate(v, v + 10, [&count](){ return ++count; });
vector<X> v;
sort(v.begin(), v.end(), [](const X& a, const X& b){ return a.v < b.v; });
20. 显式内存布局
alignas(double) unsigned char c[1024];
alignas(16) char[100];
constexpr int n = alignof(int);
21. 覆盖控制
struct B {
virtual void f() const final; // 不能被覆盖
};
22 可变参数宏(对C99的支持)
#define report(test, ...) ((test)?puts(#test):printf(__VA_ARGS__))
23. 新容器
<array>
std::array<int, 6> a = { 1, 2, 3 };
int *p = a.data();
<forward_list>
unordered_map
unordered_set
unordered_multimap
unordered_multiset
<tuple>
std::tuple<string, int> t2("ok", 123);
auto t = make_tuple(string("ok"), 10, 1.234);
string s = get<0>(t);
int x = get<1>(t);
24. 函数对象
<functional>
int f(int, char, double);
auto frev = bind(f, _3, _2, _1);
int x = frev(1.2, 'c', 7);
auto f = bind<int>(f, 7, 'c', _1);
int x = f(1.2);
25. 线程
<thread>
void foo(){ cout << "ok" << endl; }
thread t(foo);
t.join();
26. 正则表达式<regex>
27. 原子值<atomic>
28. 新时间库<chrono>
1. auto关键字
auto关键字可以在编译期自动推导变量的类型,例如:
auto x = 7;
for (auto i = v.begin(); i != v.end(); ++i){
cout << *i << endl;
}
2. for关键字
C++11为for语句提供了类似Java中for或者C#和PHP中foreach的用法:
void f(vector<double> &v){
for (auto &x : v){
cout << x << endl;
}
}
for (const auto x : { 1, 2, 3, 4 }){
cout << x << endl;
}
3. 构造函数和析构函数的控制参数
在C++98中,如果你想禁止一个类的构造函数被调用,你需要将其声明为private成员。C++11提供了一个新特性,你可以再声明构造函数时加上delete来避免构造函数被调用:
class X {
X& operator=(const X&) = delete;
X(const X&) = delete;
~X() = delete;
};
class Y {
Y& operator=(const Y&) = default;
Y(const Y&) = default;
};
例子中default的意思是使用编译器自动合成的构造/西沟函数。
4. 常量表达式
常量表达式可以在很多地方取代宏:
enum Flags { good = 0, fail = 1, bad = 2, eof = 4 };
constexpr int operator|(Flags lhs, Flags rhs){ return Flags(int(f1) | int(f2)); }
void f(Flags x){
switch (x){
case bad: ... break;
case eof: ... break;
case bad | eof: ... break;
default: ... break;
}
}
constexpr int x = bad | eof;
Flags f, constexpr x = bad | f; // error constexpr必须在编译器可以被计算
5. 表达式类型
typedef decltype(x * y) ResultType;
6. 初始化列表
C++11提供了一个新的,统一的初始化列表{}:
vector<double> v = { 1, 2, 3.45 };
list<pair<string, string> languages = {
{ "Nygaard", "Simula" },
{ "Richards", "BCPL" },
{ "Ritchie", "C" },
};
std::initializer_list<T>
void f(initializer_list<int> v){
for (auto x : v){ cout << x << endl; }
}
f({1, 2});
f({});
使用{}初始化时,不会做降低精度的类型转换(narrow)。
int a[3] = { 1, 2, 3 };
7. 委托构造函数
class X {
X(int x){ cout << x << endl; }
X() :X(10){}
X(string s) :X(lexical_cast<int>(s)){}
};
8. 类内初始化
class X {
int a = 7;
};
9. 继承构造函数
struct B {
B(){}
};
struct D : B {
using B:B;
};
10. 编译期断言
static_assert(expression, string)
11. 空指针
nullpter
12. 返回值后置声明
用于无法确定函数返回值类型的场景,不再手动指定返回值类型,而是让编译器自动推导出类型:
template<class T, class U>
auto mul(T x, U y) -> decltype(x * y){
return x * y;
}
13. 模板别名
template<N>
using int_exact = typename int_exact_traits<N>::type;
using P = [](double) -> void;
14. 可变参数模板
template<typename T, typename... Args>
void printf(const char *s, T value, Args... args){
while (s && *s){
if (*s == '%' && *++s != '%'){
cout << value;
return printf(++s, args...);
}
cout << *s++;
}
throw runtime error("extra arguments");
}
15. 右指引用
右值是在计算表达式过程中产生的非持久(临时)对象。
X &&t = f();
T tmp = move(a);
16. 原始字符串
string s = R"(\w\\\w)";
17. 自定义字面值
constexpr complex<double> operator "" i(long double d){
return {0,d};
}
auto z = 2 + 1i;
string operator""s(const char *p, size_n){
return string (p, n);
}
f("Hello\n"s);
18. 语句块属性
void f [[noreturn]] (){ throw "error"; }
for [[omp::parallel()]] (int i = 0; i < v.size(); ++i){ ... }
19. lambda表达式
vector<int> v = { 50, -10, 20, -30 };
sort(v.begin(), v.end(), [](int a, int b){ return abs(a) < abs(b); });
int count = 0;
int v[10];
generate(v, v + 10, [&count](){ return ++count; });
vector<X> v;
sort(v.begin(), v.end(), [](const X& a, const X& b){ return a.v < b.v; });
20. 显式内存布局
alignas(double) unsigned char c[1024];
alignas(16) char[100];
constexpr int n = alignof(int);
21. 覆盖控制
struct B {
virtual void f() const final; // 不能被覆盖
};
22 可变参数宏(对C99的支持)
#define report(test, ...) ((test)?puts(#test):printf(__VA_ARGS__))
23. 新容器
<array>
std::array<int, 6> a = { 1, 2, 3 };
int *p = a.data();
<forward_list>
unordered_map
unordered_set
unordered_multimap
unordered_multiset
<tuple>
std::tuple<string, int> t2("ok", 123);
auto t = make_tuple(string("ok"), 10, 1.234);
string s = get<0>(t);
int x = get<1>(t);
24. 函数对象
<functional>
int f(int, char, double);
auto frev = bind(f, _3, _2, _1);
int x = frev(1.2, 'c', 7);
auto f = bind<int>(f, 7, 'c', _1);
int x = f(1.2);
25. 线程
<thread>
void foo(){ cout << "ok" << endl; }
thread t(foo);
t.join();
26. 正则表达式<regex>
27. 原子值<atomic>
28. 新时间库<chrono>