c++之旅:函数模板

函数模板

函数模板主要是泛型在函数的中的应用,通过泛型可以让函数处理各种各样的数据类型

简单的列子

#include <iostream>
using namespace std;

template <typename T>  //定义泛型T
T add (T t1, T t2) {
    return t1 + t2;
}

int main () {
    cout << add(10.5, 0.8) << endl;
}

上面的例子中首先定义了泛型T,然后在add函数中使用了泛型,typename关键字也可以写成class。

明确指定类型
#include <iostream>
#include <string>
using namespace std;

template <typename T, typename E>  //定义泛型T
E add (T t, E e) {
    if (t > 1)
        return e + "1";
    else
        return e + "1.5";
}

int main () {
    cout << add<int, string>(10, "hello") << endl;
}

上面的代码中我们在调用add时显示的指定传入的类型

函数模板的重载

函数的模板的重载可函数的重载一个道理,都是通过函数名和函数参数列表来确定的

#include <iostream>
#include <string>
using namespace std;

template <typename T>
T test(T t) {
    return t;
}

template <typename T>
T test(T t, int n) {
    return n;
}

int main () {
    cout << test<int>(3) << endl;
    cout << test<float>(3.5, 10) << endl;
}

第一个test(3)会调用第一个函数模板,而 test(3.5, 10)会调用第二函数模板

函数包装器

模板函数中不仅能接受普通类型作为参数,还能接受函数。当使用函数作为参数时,需要用到函数包装器

#include <iostream>
#include <functional>
using  std::cout;
using  std::endl;
using std::function;

template <typename V, typename F>
V add (V v1, V v2, F f) {
    return f(v1, v2);
}

int main () {
    
    function<int(int, int)> fun = [](int v1, int v2) {
        return v1 + v2;
    };
    
    cout << add(1, 2, fun) << endl;
}

上面的代码中需引入functional库,并定义了一个函数。

function<int(int, int)> fun = [](int v1, int v2) {
        return v1 + v2;
    };

中括号中第一个int表示返回值类型,后面的小括号表示函数接受的参数。函数包装器的实质时函数指针。通过函数包装器我们可以在一个函数内部定义一个函数了。

函数包装器指向外部函数
#include <iostream>
#include <functional>
using namespace std;

void test(int i, int j) {
    cout << i << j << endl;
}

int main () {
    function<void(int, int)> fun = test;
    fun(1,3);
}

引用包装器

要想在函数模板内部修改传入的值,需要传递变量的引用或者指针,一般情况下,我们会将变量的引用传递进去,这时将函数模板参数设置为引用或者使用引用包装器。

函数接受引用
#include <iostream>
#include <string>
using namespace std;

template <typename T>
void test(T t) {
   t = 100;
}

int main () {
   int a  = 10;
   test<int&>(a);
   cout << a << endl;
}
使用引用包装器

引用包装器有些问题,尽量避免使用

#include <iostream>
#include <functional>
using namespace std;

template <typename T>
void test(T t) {
   t += 100;
}

int main () {
   int a = 10;
   test(ref(a));
   cout << a << endl;
}

上面的代码中去掉模板中的+号就会便宜错误

posted @ 2017-05-29 11:45  被罚站的树  阅读(149)  评论(0编辑  收藏  举报