美文网首页
模板与泛型 —— 函数指针作为模板参数

模板与泛型 —— 函数指针作为模板参数

作者: 从不中二的忧伤 | 来源:发表于2020-05-17 20:48 被阅读0次
一、typename 的用法

1、typename 和 class 在模板定义中,声明模板参数为类型参数时,可以互换。

template<typename T>
T Add(T val1, T val2)

template<class T>
T Add(T val1, T val2)

2、使用类的类型成员时,用 typename 标识其后跟的是个类型。
例一

template<typename T>
class myvector
{
public:
    typedef T* myiterator;  // 用 typedef 定义的为类型成员
public:
    myiterator mybegin();  // 返回容器中的第一个元素
};

template<typename T>
// 1. 需要用 myvector<T>:: 访问类型成员 myiterator
// 2. 编译器只有在实例化时才能确定 myvector<T>:: 后面跟着的是类型还是静态成员变量,所以需要用 typename标识其后跟着的是类型。
typename myvector<T>::myiterator myvector<T>::mybegin()
{
    //todo 
}

例二
size_type 为 string / STL 的类型成员, typedef usigned int size_type
typename 表示 T::size_type 返回的也是一个类型

template<typename T>
typename T::size_type getlength(const T& c)
{
    return c.size();
}

string str = "hello world";
cout << getlength(str) << endl;
二、函数指针作其他函数的参数
// 定义函数指针类型
typedef int (*FunType)(int, int);

int myfunc(int val1, int val2)
{
     return val1 + val2;
}

void recvfunc(int i, int j, FunType pf)
{
    cout << pf(i, j) << endl;
}

int main()
{
    recvfunc(1, 2, myfunc);
    return 0;
}
三、函数指针作为函数模板参数

下面的例子中,编译器将模板参数 F 解释成函数指针类型 FunType

typedef int (*FunType)(int, int);

int myfunc(int val1, int val2)
{
     return val1 + val2;
}

template<typename T, typename F>
void tfunc(const T &i, const T &j, F pf)
{
    cout << pf(i, j) << endl;
}

int main()
{
    tfunc(1, 2, myfunc);
    return 0;
}
四、对象作为函数模板参数
template<typename T, typename F>
void tfunc(const T &i, const T &j, F pf)
{
    cout << pf(i, j) << endl;
}

class Test
{
public:
    Test() { cout << "construct" << endl; }
    Test(const Test& t) { cout << "copy construct" << endl; }
    
    int operator()(int v1, int v2) const
    {
        return v1 + v2;
    }
};

int main()
{
    Test t;    // 调用构造函数
    tfunc(1, 2, t);    // 调用拷贝构造函数
}

执行结果:


image.png

上面的程序中,编译器将模板参数 F 解释为 Test 类型对象(因为在 Test 类中重载了括号Test(int, int),所以Test类对象可以当作函数调用的格式使用),并将 t 传递给了 pf (pf相当于临时对象),调用了拷贝构造函数。

使用临时对象:

int main()
{
    tfunc(2, 3, Test());
}

执行结果:


image.png

使用临时对象,则模板函数直接承接此临时对象,省去了拷贝构造过程(也省去一次析构过程),更加节省时空。

五、默认模板参数
类模板

类模板的实例化必须显示声明模板参数(<>不可省略)
类模板的缺省参数

template<typename T=string, int size=10>
class myarray
{
private:
    T arr[size];
};

int main()
{
    // 完全使用模板参数缺省值
    myarray<> arr1;

    // 使用部分模板参数缺省值
    myarray<int> arr2;

    return 0;
}
函数模板

C++11 开始,支持函数模板默认参数
例一: 对象作为函数模板默认参数

class Test
{
public:
    Test() { cout << "construct" << endl; }
    Test(const Test& t) { cout << "copy construct" << endl; }
    
    int operator()(int v1, int v2) const
    {
        return v1 + v2;
    }
};

// 为 F 提供默认参数 Test 类
template<typename T, typename F=Test>
// 为 pf 提供临时对象 F(),即为Test()
void tfunc(const T &i, const T &j, F pf=F())
{
    cout << pf(i, j) << endl;
}

int main()
{
    tfunc(2, 5);
    return 0;
}

例二:函数指针作为函数模板默认参数

typedef int (*FunType)(int, int);

int myfunc(int val1, int val2)
{
    return val1 + val2;
}
// 为 F 提供默认参数 FunType 类型
template<typename T, typename F=FunType>
// pf 默认为 myfunc
void tfunc(const T &i, const T &j, F pf=myfunc)
{
    cout << pf(i, j) << endl;
}

int main()
{
    tfunc(2, 5);
    return 0;
}

例三:函数模板的默认非类型参数

template<int T=10>
void tfunc()
{
    cout << T << endl;
}

int main()
{
    tfunc();     // 输出10
    tfunc<>();  // 输出 10
    tfunc<12>();    // 输出12
    return 0;
}

相关文章

  • 模板与泛型 —— 函数指针作为模板参数

    一、typename 的用法 1、typename 和 class 在模板定义中,声明模板参数为类型参数时,可以互...

  • C++函数模板

    函数模板 函数模板与常规函数相比,就是使用template<>定义了泛型,然后在函数中的任意地方使用这个泛型。 如...

  • C++系列 --- 模板概念,函数模板定义、调用

    今天呢,我们来学习一下C++的模板与泛型,主要学习模板的概念、函数模板的定义和调用。 一、模板的概念 1、所谓泛型...

  • C++模板与泛型---模板概念,函数模板定义、调用

    今天呢,我们来学习一下C++的模板与泛型,主要学习模板的概念、函数模板的定义和调用。 一、模板的概念 1、所谓泛型...

  • 模板与泛型 —— 模板模板参数

    一、模板模板参数 一、模板模板参数 考虑在类模板中,有成员变量 : vector myt; vector 实...

  • GeekBand C++第六周学习感悟

    函数模板笔记 模板是通用的函数描述,也就是说它们使用泛型来定义函数,其中的泛型可用具体的类型替换。通过将类型作为参...

  • c++模板

    模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。可以使用模板来定义函数和类 函数模板 模板...

  • GeekBand STL与泛型编程 第一周

    1.模板观念与函数模板 课程主要内容 C++模板简介 泛型编程 容器 进阶 C++模板简介   generic t...

  • 模板特化

    模板是C++泛型编程编程的基础,STL从头到尾都是模板泛型编程 函数模板 类模板 几个需要注意的点1. 类模板的和...

  • Geekband-first week of part3

    1.模板是通过泛型的形式表现或运行 2.模板可以节省代码量,通过一族泛型参数的类或者函数可以体现 3.c++主要有...

网友评论

      本文标题:模板与泛型 —— 函数指针作为模板参数

      本文链接:https://www.haomeiwen.com/subject/jabsohtx.html