Chapter 7 Advances in Functions
Default Arguments(difference between Parameter and Argument)
注意这只有在C++中才适用,C中无法使用!
同时方框里面的三种全部对应下面的函数体。
- Parameter(参数):指函数定义时声明的变量,用于接收传入的值。在提供的代码中,函数
norm(float x, float y, float z)
的x
、y
和z
就是参数。它们在函数定义时出现,类似于函数的“占位符”,定义了函数在调用时需要传递哪些值。
例如,float norm(float x, float y, float z = 0);
中,x
、y
和z
是函数的参数,z
有一个默认值为0。如果没有传入z
的值,z
将自动使用这个默认值。 - Argument(实参):指在函数调用时传递给函数的实际值。例如,调用
norm(3.0f)
时,3.0f
就是这个函数调用的实参,它被传递给x
参数。实参在函数调用时提供,直接影响函数的执行。
设定默认参数的规则:必须从尾部的参数开始定义,例子中,必须先定义z的默认参数,设定y的参数,再到x的参数,反过来是不可以的。
Function Overloading
c++中同时判断函数名和参数列表,参数列表和函数名全部相同才是同一个函数。
但是返回类型不考虑,也就是说,如果有两个函数体,函数名和参数列表完全相同,但是return type不一样的话,他们过不了编译器。
如果输入类型是int x,float y的两个参数比如说输入是2,2.2,如果这个时候有函数overload,那么编译器会报错,因为发生了ambiguous。
Function Templates 这块有点不是特别懂
Why function templates
如果上面三个函数有300行代码,那么维护起来特别麻烦,因为他们的实现逻辑相同,我们可以有更好的办法来写这个函数,而不是写三遍。
Explicit instantiation
编译器看到第一段方框的时候不会执行,因为他也不知道该怎么做加法(不知道类型),但是要实例化。
看到第二段方框的时候,生成三个不同的函数,就像三个overload的函数。
再执行的时候就可以按照上面的overload一样的概念来执行。
既然已经提供了返回类型和函数参数类型,为什么还需要显式提供模板参数呢?
模板函数的编译器行为取决于 模板参数推导 和 显式实例化 的规则。在某些情况下,编译器无法通过函数参数或返回类型唯一地确定模板参数,因此我们需要显式指定 <>
中的模板参数。
template double sum<double>(double, double);
template double
:
这是模板的返回类型,表示 sum
函数的返回值类型是 double
。
sum<double>
:
这是模板的显式实例化部分,表示我们要求编译器为模板参数 T
生成double
类型的函数实例。这个里面的double就替换了模板中的T。
template<typename T> T sum(T x, T y) { return x + y; }
通过 sum<double>
,我们明确告诉编译器,这里的 T
应该被替换为 double
。
Implicit instantiation
再探第二个方框。
template double sum<double>(double, double);
- 这是显式实例化(explicit instantiation),表示告诉编译器直接生成一个
sum
函数,它的模板参数是double
类型。 <double>
表示模板参数的类型是double
,因此sum<double>(double, double)
函数专门处理double
类型的参数。- 这意味着编译器会直接为
double
类型生成一个具体的sum
函数实现,而不是等待推导模板参数。
- 这是显式实例化(explicit instantiation),表示告诉编译器直接生成一个
template char sum<>(char, char);
- 这里是隐式实例化(implicit instantiation),即模板参数通过函数参数推导(deduction)来决定。
- 你没有显式提供模板参数
<char>
,编译器会根据传入的实参类型自动推导出模板参数是char
类型。 - 当你调用类似
sum('a', 'b')
时,编译器会推导出sum<char>(char, char)
,并为char
类型生成具体的sum
函数实现。
template int sum(int, int);
- 同样是隐式实例化,编译器根据函数参数的类型推导出模板参数。
- 在这里,当你调用
sum(3, 4)
时,编译器会推导出sum<int>(int, int)
,并生成int
类型的具体函数实现。 - 虽然模板参数
<int>
没有显式写出来,但编译器通过实参推导得知int
是模板参数。
Function template specialization
但是这种咋办?我们的+不可以对这种type进行加法运算啊!!x是一个结构体,y是一个结构体,结构体相加会报错的!!
还有特例化
Function Pointers and References
Function pointers
其中第三行给出了函数指针的定义方式。
注意函数指针必须指向跟他定义的时候有完全相同的参数type和返回type.
Function references
注意括号绝对不可以省略!!也必须要开始就初始化。
Recursive Functions
就简单介绍下。