模板与泛型编程

一、函数模板

模板定义以关键字template开始,后跟一个模板参数列表,在模板定义中,模板参数列表不能为空。

模板类型参数:类型参数前必须使用class或typename关键字。

非类型模板参数:表示一个值而不是一个类型

数组引用形参:

//&arr两端的括号必不可少
void print(int(&arr)[10])
{
    for (auto elem : arr)
    {
        cout << elem << endl;
    }
}
//用于比较字符串常量
//compare("hi","mom")
template<unsigned N,unsigned M>
int compare(const char(&p1)[N], const char(&p2)[M])
{
    return strcmp(p1, p2);
}

一个非类型参数可以是一个整型,或者是一个指向对象或函数类型的指针或引用。绑定到非类型整型参数的实参必须是一个常量表达式。绑定到指针或引用非类型参数的实参必须具有静态的生存期。我们不能用一个普通(非static)局部变量或动态对象作为指针或引用非类型模板参数的实参。指针参数也可以用nullptr或一个值为0的常量表达式来实例化。
inline或constexpr说明符放在模板参数列表之后,返回类型之前。

template <typename T> inline T min(const T&, const T&);
inline template <typename T>  T min(const T&, const T&);//出错

通常,当我们调用一个函数时,编译器只需要掌握函数的声明。类似地,当我们使用一个类类型的对象时,类定义必须是可用的,但成员函数的定义不必已经出现。因此,我们将类定义和函数声明放在头文件中,而普通函数和类的成员函数的定义放在源文件中。
为了生成一个实例化版本,编译器需要掌握函数模板或类模板成员函数的定义。所以函数模板和类模板成员函数的定义通常放在头文件中。

原文地址:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/4413886.html