容器之迭代器,获取迭代器之后,如有容器使用insert()方法,迭代器失效。
——2020/11/20 22:27
std::cin.get(char *, int)将一直读取输入,直到到达行尾或读取了int-1个字符为止,换行符等会留在输入队列中。 std::cin.get(char *, int)读取空行将导致cin为false。
必须在声明引用变量时进行初始化。
引用 接近 解除引用的const指针
函数重载(多态),关键是函数的参数列表——也称为函数特征标(function signature),函数名,参数数目、类型、排列顺序
函数模板 /泛型/通用编程 参数化类型
关键字:template typename/class
template <typenemae AnyType> // template <class T> void func(AnyType &a, AnyTYpe &b) { AnyType temp; temp = a; a = b; b = temp; }
模板重载
模板的局限性,如结构等类型不可执行某些操作,解决:运算符重载,或,为特定类型具体化模板定义
具体化方式
隐式实例化 implicit instantiation:使用模板生成函数定义
显式实例化 explicit instantiation:显式说明使用模板生成函数定义 前缀:template,好像没必要使用??
显式具体化 explicit specialization:不使用模板生成函数定义,使用专门为特定类型显式定义地函数定义 前缀:template <>
// twoswap.cpp -- specialization overrides a template #include <iostream> template <class T> void Swap(T &a, T &b); struct job { char name[40]; double salary; int floor; }; // template <> void Swap(job &j1, job &j2); // explicit specialization template <> void Swap<job>(job &j1, job &j2); // explicit specialization // template void Swap<char>(char &, char&); // explicit instantiation template void Swap(char &, char&); // explicit instantiation, generates void Swap(char &, char &) void Show(job &j); // void Swap(job &j1, job &j2); int main() { using namespace std; cout.precision(2); cout.setf(ios::fixed, ios::floatfield); int i = 10, j = 20; cout << "i, j = " << i << ", " << j << ".\n"; cout << "Using compiler-generated int swapper:\n"; Swap(i,j); // implicit instantiation, generates void Swap(int &, int &) cout << "Now i, j = " << i << ", " << j << ".\n"; char a = 'a', b = 'b'; cout << "a, b = " << a << ", " << b << ".\n"; cout << "Using compiler-generated char swapper:\n"; Swap(a,b); // uses void Swap(char &, char &) cout << "Now a, b = " << a << ", " << b << ".\n"; job sue = {"Susan Yaffee", 73000.60, 7}; job sidney = {"Sidney Taffee", 78060.72, 9}; cout << "Before job swapping:\n"; Show(sue); Show(sidney); Swap(sue, sidney); // uses void Swap(job &, job &) cout << "After job swapping:\n"; Show(sue); Show(sidney); // cin.get(); return 0; } template <typename T> void Swap(T &a, T &b) // general version { T temp; temp = a; a = b; b = temp; } // swaps just the salary and floor fields of a job structure template <> void Swap<job>(job &j1, job &j2) // specialization { double t1; int t2; t1 = j1.salary; j1.salary = j2.salary; j2.salary = t1; t2 = j1.floor; j1.floor = j2.floor; j2.floor = t2; } // void Swap(job &j1, job &j2) // { // double t1; // int t2; // t1 = j1.salary; // j1.salary = j2.salary; // j2.salary = t1; // t2 = j1.floor; // j1.floor = j2.floor; // j2.floor = t2; // } void Show(job &j) { using namespace std; cout << j.name << ": $" << j.salary << " on floor " << j.floor << endl; }
关键字 decltype ,类型推断
后置返回类型
auto func(int x, float y) ->double
最佳可行函数。通常,从最佳到最差的顺序为:
1,完全匹配,但常规函数优先于模板;2,提升转换,如char和short自动转换为int,float自动转换为double;3,标准转换,如int转换为char,long转换为doule;4,用户定义的转换,如类声明中定义的转换。
如果两个最匹配的函数都是模板,则较具体的优先。“最具体”,执行的转换最少。
完全匹配允许的无关紧要转换:从实参到形参 T->T &,T & -> T,T [] -> * T,T (argument-list) -> T (*) (argument-list),T -> const T,T -> volatile T,T * -> const T,T * -> volatile T;
! const与非const之间的区别只适用于指针和引用。
存储说明符
auto C++11之前显式指出变量为自动变量,C++11中自动类型推断
register 指示寄存器存储,C++11中显式指出变量是自动的
static 全局变量时表示内部链接性,局部时表示静态存储持续性
extern 引用声明,声明引用在其他地方定义的变量
thread_local 线程持续性
mutable 根据const解释;const结构或类的mutable成员可以被修改。
cv-限定符
const 常量,初始化后不可进行修改;全局时内部链接性,结合extern可定义/初始化为外部链接性常量,在其他文件extern const引用声明。
volatile 即使程序没有对内存单元进行修改,其值也可能发生变化。
单定义规则:变量只能有一次定义。适用于非内联函数。
使用外部变量(静态,外部链接性),使用 extern 关键字声明,引用声明且不进行初始化
static 关键字
(register 关键字)
持续性:自动(函数或代码块中,栈内存)、静态(函数外或static)、线程(关键字thread_local)、动态(new delete,也称 自由存储 free store 或 堆 heap)
作用域(scope):
链接(linkage):
自动 变量
静态 变量(无链接性、外部链接性、内部链接性)
5种变量储存方式
存储描述 持续性 作用域 链接性 如何声明 自动 自动 代码块 无 在代码块中;自动变量 寄存器 自动 代码块 无 在代码块中,使用关键字register; 静态,无链接性 静态 代码块 无 在代码块中,使用关键字static;静态局部变量 静态,外部链接性 静态 文件 外部 不在任何函数内;全局变量,在其他文件使用时先使用extern引用声明 静态,内部链接性 静态 文件 内部 不在任何函数内,使用关键字static;静态全局变量 作用域解析运算符(::)
函数链接性,默认extern外部链接性,可以使用static关键字设置为内部链接性,声明和定义时都必须使用关键字static。
函数查找,若该文件中函数原型指出是静态的,将只在该文件中查找函数定义;否则,在所有的程序文件中查找。如果找到两个定义,将报错。如果在程序文件中没有找到,将会在库中搜索。
语言链接性
extern "C" void func1(int); // use C protocol for name look-up,可能是_func1,C语言链接
extern void func2(int); // default use C++ protocol for name look-up,可能是_func2_i,C++语言链接
extern "C++" void func3(double, double); // explicit use C++ protocol for name look-up,可能是_func3_d_d
new delete