c++——函数模板

1. 定义

template<typename T>

以关键字template开头,后面跟一个模板参数列表,列表里面用逗号将多个模板参数隔开定义的注意事项。

模板的编译

  • 当编译器遇到一个模板定义时,并不生成代码。只有当实例化处模板的一个特定版本时,编译器才会生成代码
  • 重点:通常,当我们调用一个函数/定义实例化一个类时,编译器只需掌握函数的声明/类的声明即可,因此可以把函数/类的声明放置在头文件,而把函数/类的定义放置在源文件中。但是模板则不同:为了实例化模板函数,编译器必须掌握函数模板/类模板成员函数的声明和定义,因此只能将模板函数/类的声明和定义都放置在头一个头文件/源文件中(重点)

2. 函数模板和模板函数

  • 函数模板:一个模板(是模板)
  • 模板函数:调用函数模板时生成的函数(是函数),也称为函数模板的实例化

一个模板参数列表只和一个函数模板相对应。因此每定义一个函数模板就需要重新定义一个模板参数列表

//定义模板以及一个函数模板
template <typename T>
int compare(const T &v1, const T &v2);
 
int main()
{
    compare(1, 2);       //模板函数,也称为模板的实例化
    compare("ABC","DEF");//模板函数
    return 0;
}

3. 模板类型参数

  • 模板参数列表不能为空
  • 模板参数既可以用typename声明,也可以使用class声明。不过建议前者
//定义模板以及一个函数模板
template <typename T, class U>
int compare(const T &v1, const U &v2);
 
int main()
{
    compare(1, 1);    //T为int,U也为int
    compare(1,"DEF"); //T为int,U也为string
    return 0;
}

4. 非类型模板参数

  • 除了定义上面的模板类型参数,我们也可以定义非类型参数。
  • 一个非类型参数表示一个值而非一个类型。并且通过特定的类型名定义而非typename或class来定义
  • 当一个模板被实例化时,非类型参数被用户提供或者编译器推断的值所代替。
  • 重点:一个非类型参数可以是一个整型、一个指向对象或函数的指针(或引用)。且实参必须是一个常量表达式
//定义模板以及一个函数模板。
template <unsigned N, unsigned M>
int compare(const char(&p1)[N], const char(&p2)[M])//传入数组的引用来比较数组大小
{
    return strcmp(p1, p2);
}
 
int main()
{
    compare("hi","Jorry");//编译器会使用字面值常量的大小来代替N和M
    return 0;
}

5. inline、constexpr函数模板

  • 函数模板可以声明为inline或constexpr。但是这些关键字必须放在函数的返回值类型前面,模板参数列表的后面
template<typename T>  //正确
inline T func(T const&);
 
constexpr template<typename T> //错误,constexpr位置错误
T func2(T const&);

6. 定义类型无关代码

  • 当我们定义函数模板时,如果函数能处理的功能只限于一些特定的情况,而不能作用于大多数的情况,那么这个函数模板的操作性与可移植性就比较差
  • 为了解决上面这个问题,我们在定义函数模板时,就需要考虑类型无关与可移植性

案例:

  •  下面这个函数模板如果调用它比较两个指针,而这两个指针未指向相同的数组,则代码的行为是未定义的
template <typename T>
int compare(const T& s1, const T& s2)
{
	if(s1 < s2)
		return -1;
	else if(s1 > s2)
		return 1;

	return 0;
}
  •  下面我们编写了这个函数模板,也可以用于传入指针也可以正常使用的函数模板(但是还不是最完美的,所以在定义时,要考虑各种因素而达到更高的标准)
template <typename T>
int compare(const T& v1, const T& v2)
{
    if (less<T>()(v1,v2))
        return -1;
    if (less<T>()(v2, v1))
        return 1;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值