利用方法
将鼠标移至 "C++11特性总汇" 上面, 右方出现导航小图标, 点击后在导航列表右上角点击固定, 再拖至左方空闲区域
该总汇编号与书中划一, 如有不明确的地方请检察原著
预定义宏
- 211.预定义宏
- 212.__func__宏返回当前所在函数或布局体名字
- 213.#pragma once/_Pragma(“once”)该头文件只编译一次
- 214.__VA_ARGS__变长参数宏定义 #define PR(...) printf(__VA_ARGS__)
- 215.宽窄字符串的连接
支持long long int类型
22.long long int n至少有64位
差别类型运算拓宽
23.(int)a + (long long int)b a会被提升为long long型后再举行运算
__cplusplus宏
24.用于C/C++混合编写, __cplusplus = 201103L可用作检测编译器所支持的C++版本- #ifdef __cplusplus
- extern "C" {
- #endif
- //some code
- #ifdef __cplusplus
- }
- #endif
复制代码 assert断言
- (1) 包罗在的断言assert(n > 0);运行时若n不大于0则报错
(2) 静态断言static_assert(sizeof(a) == sizeof(b), "must have same width");编译时报错,不可利用变量举行静态断言
noexcept关键词
- void func() noexcept(true);
复制代码 如有非常,选择不抛出,而是直接终止运行并报错,括号内常量表达式true=不抛出, false=抛出
花括号初始化非静态成员
- private:
- string name{"ABC"};
复制代码 允许对非静态成员利用sizeof
- private:
- int n; //sizeof(class::n)可编译通过
复制代码 友元模板
29.可在模板利用友元friend T;
final/override关键词
- private:
- void func() final; //派生不可重载
- void oldFunc() override; //重载必须同名,同参数,同常量性,且被重载的是虚函数
复制代码 默认模版类型
- template<typename T1, typename T2 = int> class C1; //通过
- template<typename T1 = int, typename T2> class C2; //报错,类模版默认类型需要从右往左
- template<typename T1 = int, typename T2> void func(T1 a, T2 b); //通过,函数模版没有这规定
复制代码 外部模版
- extern template void func<int>(int);
复制代码 继续构造函数
- struct B: A{
- using A::A;
- };
复制代码 委派构造函数
- class A{
- public:
- A() : A(1234){} //先调用A(int)
- A(int n1) : A(n1, 'C'){} //先调用A(int, char)
- A(char c1) : A(2, c1){} //先调用A(int, char)
- private:
- A(int n2, char c2) : my_int(n2), my_char(c2){}
- int my_int;
- char my_char;
- }
复制代码 应用于模版:- class A{
- public:
- A(vector<int> &v) : A(v.begin(), v.end());
- A(deque<short> &d) : A(d.begin(), d.end());
- private:
- template<class T> A(A n1, T n2) : my_list(n1, n2) {}
- list(int) my_list;
- }
复制代码 捕捉非常:- class A{
- public:
- A()
- try : A(1234) {init();}
- catch(...) {error();}
- A(int n) {throw 0;}
- //构造时执行error(), 而不执行init()
- }
复制代码 右值引用
- class A{
- public:
- A() : my_ptr(new int(1234)) {}
- A(A ©) : my_ptr(new int(*copy.my_ptr)) {}//新申请一块内存,避免重复析构同一块内存
- ~A() {delete my_ptr;}
- int *my_ptr;
- }
复制代码- class A{
- public:
- A() : my_ptr(new int(1234)) {}
- A(const A& copy) : my_ptr(*copy.my_ptr) {}
- A(A&& move) : my_ptr(move.my_ptr) {move.my_ptr = nullptr;}
- ~A() {delete my_ptr;}
- int* my_ptr;
- }
- A GetTmp() {
- A tmp;
- return tmp;
- }
- int main(){
- A one = GetTmp();
- }
复制代码 1.执行GetTmp(),创建A1并初始化后返回,
2.创建并初始化A2,即A2(A1), 执行的是move而不是copy,它将A1的指针赋值给A2,并将A1的指针清掉,
3.析构A1,由于指针清掉了,所以初始化时的内存没有被开释
4.创建并初始化one,即one(A2),重复第2步,第3步
5.析构one,此时内存才真正被开释,它是A1初始化时申请的
- 333.著名字的是左值, 没名字的是右值, 左值*p=1234, 右值p=1234
- 334.在中提供了std::move函数,它将左值强制转化为右值引用
- 335.swap(T a, T b)函数利用移动语义举行交换,
移动构造函数不应该写抛出非常,
编译选项-fno-elide-constructors关闭优化以利用移动/拷贝语义,否则变量直接替换成右值举行编译
引用折叠规则:- typedef int T;
- typedef T& TR; //or typedef T&& TR
- TR a; //or TR& a , TR&& a
复制代码 TR定义为T&时,a的类型都是A&
TR定义为T&&时,TR/TR&&的类型为A&&,TR&的类型为A&- template <typename T, typename U>
- void PF(T&& t, U& func){
- func(std::forward<T>(t));
- }
复制代码 forward()与move()功能相同,完美转发可以或许把引用类型正确传给调用函数
explicit显式转换操作符
- class A{}
- class B{
- public:
- explicit operator A() const {return A();}
- }
- void func(A a){}
- void main(){
- B b;
- A a1(b); //通过,直接初始化
- A a2 = b; //错误
- A a3 = static_cast<A>(b); //通过,显式转换
- func(b); //错误
- }
复制代码 列表初始化
- 头文件,声明一个以initialize_list模版类为参数的构造函数,就可以或许使自定义类利用列表初始化
- void func(initializer_list<int> numbers){}
- int main(){
- func({1, 2, 3});
- func({});
- }
复制代码 352.利用花括号初始化可以防止类型收窄- const int x = 1234;
- char a = x; //通过
- char b = {x}; //错误
- char* c = new char(1234); //通过
- char* d = new char{1234}; //错误
复制代码 36.POD类型
37.团结体
38.用户自定义字面量
内联名字空间
- inline namespace space1{
- class A{};
- }
- namespace space2{
- A a;//A in space1
- class A{};
- A b;//A in space2;
- }
复制代码 模版的别名
- template<typename T> using NewName = std::map<T, char*>;
- NewName<int> a; //等同于std::map<int, char*> a;
复制代码 SFINAE规则
- struct A{ typedef int my_int;
- };
- template <typename T>
- void func(typename T::my_int) {} //#1
- template <typename T>
- void func(T) {} //#2
- int main(){
- func<A>(1234); //调用#1,因为存在 A::my_int
- func<int>(1234); //调用#2,因为不存在 int::my_int
- }
复制代码 >>右尖括号
41.两个右尖括号>在模板中不再被判断为右移, 需要右移需要加圆括号()
auto类型推导
- int a = 1;
- auto b = a; //b的类型为int
复制代码 编译时推导
1): auto不能作函数形参类型
2): auto不能对布局体中的肥静态成员举行推导
3): auto不能声明数组
4): auto不能在实例化模板时作为模板参数
decltype类型推导
43.- int a = 1;
- decltype(a) b; //b的类型为Int
- uding size_t = decltype(sizeof(0)); //与using/typydef合用
复制代码 编译时推导
1): decltype不能推导重载的函数
2): decltype将亡值推导为右值引用
3): decltype将左值推导为引用, 如 三元运算符, 带圆括号的左值, ++i, arr[0], *ptr
4): 以上都不是,则推导为本类型
追踪返回类型
- template<typename T1, typename T@>
- auto Func(const T1& a, const T@& b) -> decltype(a + b){
- return a + b;
- }
复制代码 编译时推导
基于范围的for循环
- vector<int> MyVector= {1, 2, 3, 4};
- for(auto p : MyVector)
- {
- cout << p << endl; //p是解引用后的对象, 无需再*p解引用
- }
复制代码 智能指针
- enum class MyEnum: char{ e1, e2, e3}; //定义一个以char为底层实现的强类型枚举
- MyEnum a = e1; //错误
- MyEnum b = MyEnum::e1; //通过
- MyEnum c = 2; //错误
- Myenum d = MyEnum::e2;
- if(d > 1){} //错误
- if((char)d > 1){} //通过
复制代码 unique_ptr只允许唯一指针指向内存
shared_ptr则允许共享同一块内存,它在实现上接纳了引用计数,只有在计数归零时才真正开释内存
weak_ptr不拥有控制权,其成员函数lock()返回其指向内存的一个shared_ptr对象,若其内存无效则返回nullptr
constexpr常量表达式
函数:- unique_ptr<int> up1(new int(11)); //无法被复制
- unique_ptr<int> up2 = up1; //编译错误, 指针唯一
- unique_ptr<int> up3 = move(up1); //up1的控制权转移给up3
- up3.reset(); //显式释放
- up1.reset(); //不会出错
复制代码 1): 函数体只能有单一的return返回语句
2): 函数必须有返回值(不能为void)
3): 利用前必须已定义,即函数定义写在调用函数前面(放至后面则出错)
4): return返回语句表达式中必须是一个常量表达式,且不能是运行时函数
值:- constexpr int GetConst(){return 1;}
复制代码 它是编译时期的值,编译器可以选择不为它生成数据
自定义类: 必须对构造函数加上constexpr关键词1): 构造函数的函数体必须为空
2): 初始化列表只能由常量表达式来赋值
变长模板
- struct MyType{
- constrxpr MyType(int x): my_int(x){}
- int my_int;
- }
- constexpr MyType mt = {2};
复制代码 typename之后带...来阐明这是一个参数包,该包名字为SomeType
构造类型B时,会调用B的私有基类构造函数,并举行参数包展开
即实际上执行的是A xy;- template <typename T1, typename T2>
- class A{};
- template <typename... SomeType>
- class B: private A<SomeType...>{};
- B<int, char> xy;
复制代码 递归定义,在参数个数为0时结束,从右往左
参数包可以展开的位置:
1): 表达式
2): 初始化列表
3): 基类描述列表
4): 类成员初始化列表
5): 模板参数列表
6): 通用属性列表
7): lambda函数的捕捉列表- template <typename... B>
- class MyClass;
- template <typename A, typename... B>
- class MyClass<A, B...>: private MyClass<B...>{
- A my_a;
- };
- template<>
- class MyClass<>{};
复制代码 <blockquote>原子操作
[code]atomic_int at1 {0};atomic at2 {0};int Set(){ at1 = 1; at2 = 2;}int Show(){ cout |