1. 函数模板只能在全局中定义,或者是在类中定义。不可以在函数中(例如 main 函数中被定义)
2. 举个例子:函数模板的定义和使用
sum() 函数的函数定义就是:
#include <iostream>
using namespace std;
template <typename R>
R sum(R a, R b) {
return a+b;
}
int main()
{
int a=3, b=4;
cout<< sum<int>(a,b) <<endl;
cout<< sum(a,b) <<endl;
return 0;
}
可以显示得使用<数据类型> 来指明 typename 中的R的含义,也可以通过传入参数让编译器自己意会。但是编译器一会会存在意会错误的情况,因此更建议直接显示得指明
2. 函数作为另一个函数的参数:
可以使用 C++ 中的函数指针或 std::function
对象来实现。函数指针是一个指向函数的指针,而 std::function
是一种通用的函数对象类型,可以存储任何可调用对象(例如函数、函数指针、Lambda 表达式等)。
这里注意:lambda 表达式 默认是 const类型的,因此,无论是[&] [ ] [=] 都默认不会影响lambda表达式外的值
下面是一个同时用到 lambda 和 类的代码示例:
#include <iostream>
#include <functional>
using namespace std;
template <typename R>
R foo(function<double(R)> func, int key)
{
return func(key);
}
template <typename R>
R foo2(function<R()> func, R key)
{
return func() + key;
}
int main()
{
int x = 10;
double res;
res = foo<int>(
[&](int val) {
cout<<"val:"<<val<<endl;
val*=10.0; //此时改动的就是形参副本Val,承接的就是foo()中定义的key的数值,在当前中,key=x=10;
return val;
}, x);
cout << "res:"<<res<<endl;
cout << "执行第1个foo后的x值:" << x << endl;
res = foo<int>(
[&](int) { //由于我们lambda函数可以直接捕获处在同一作用域中的x变量,因此实现lambda函数逻辑就无须再指定参数参与了,
//之所以指明参数类型是为了匹配lambda函数在foo模板函数中定义的参数类型:function<double(R)>
cout<<"x:"<<x<<endl;
x*=10.0; //此时改动的是捕获到的当前作用域中的变量x,当前作用域=当前lambda所在的函数 ==> main()函数中
//因此捕获的就是main()函数定义的 x 变量
return x;
}, 200); // 因此,这个 200 数值其实是没有用的,因为200 传给了foo 函数作为参数key,foo中的参数 func 函数的形参为空,没有内容,所以没用到
cout << "res:"<<res<<endl;
cout << "执行第2个foo后的x值:" << x << endl;
res = foo2<int>(
[&](){
x += 22;
return x; //如果忘写了return ,那么会报错:main.cpp:4 error: could not convert ‘main()::{x}’ from ‘main()::’ to ‘std::function’
},
200 );
cout << "res:"<<res<<endl;
cout << "执行第3个foo后的x值:" << x << endl;
return 0;
}