引用变量
对于形参为const引用的C++函数,如果实参不匹配,则其行为类似值传递,为确保原始数据不被修改,将使用临时变量来存储值
1 2 3 4 5 6 7 8 9 10 11 12
| #include <iostream>
double refcube(const double &v) { return v * v * v; }
int main() { long long x = 5; double res = refcube(x); std::cout << res << std::endl; return 0; }
|
因此尽量使用const的原因有:
引用一般用于类对象,类设计的语义常常要求使用引用
默认参数
必须从右向左添加默认值
1 2
| int f(int x, int y = 1, int z = 1) int g(int x, int y = 1, int z)
|
函数重载
特征标(参数列表)不同的函数可以重载,跟函数返回值类型没关系
函数模板
1 2 3 4 5 6 7
| template <typename T> void swap(T &a, T &b) { T tmp; tmp = a; a = b; b = tmp; }
|
对于同一个函数,并非所有类型都使用同一算法,因此模板定义也可以重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| template <typename T> void swap(T &a, T &b) { T tmp; tmp = a; a = b; b = tmp; } template <typename T> void swap(T a[], T b[], int n) { T tmp; for (int i = 0; i < n; ++i) { tmp = a[i]; a[i] = b[i]; b[i] = tmp; } }
|
显式具体化:针对模板的一个特定类型提供一个特殊实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| struct job { char name[40]; double salary; int floor; };
template <typename T> void swap(T &a, T &b);
template <> void swap<job> (job &j1, job &j2);
template <typename T> void swap(T &a, T &b) { T temp; temp = a; a = b; b = temp; }
template <> void swap<job> (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; }
|
优先级:非模板函数 > 具体化 > 常规模板
隐式实例化:有一个常规模板定义,有相关类型调用导致编译器隐式地定义了一个该类型的函数
1 2 3 4 5 6 7
| template <typename T> void print(const T& value) { std::cout << value << std::endl; }
print(5); print("hello");
|
显式实例化:告诉编译器为模板的特定类型生成实例化代码的过程,而不是等到模板被实际用到时才生成,这可以减少编译时间,因为模板的实例化代码只生成一次,即使在多个地方使用同一模板的相同类型也是如此
1
| template void print<int>(const int&);
|
decltype可以在不知道表达式类型的情况下,将该类型用于变量声明、函数返回类型等场景
1 2 3 4 5 6 7 8 9 10 11
| #include <iostream>
template<typename T1, typename T2> auto f(T1 a, T2 b) -> decltype(a + b) { return a + b; }
int main() { std::cout << f(1, 2) << '\n'; return 0; }
|