cpp 模板函数,类模板(1)

对应《c++ primer 第五版》的第16章前半部分,这里是一个简单的总结。

为了防止对每个不同的类型都定义一个函数,可以使用通用的模板,一个函数模板就是一个公式,可用来生成针对特定类型的函数版本。

模板定义以template开始,后面跟一个模板参数列表,用< >括起来。
模板定义中,模板参数列表不能为空。

模板参数列表就像函数的参数列表一样,在运行时要用实参来初始化形参。
当使用模板时,显式或隐式地指定模板实参,将其绑定到模板参数上。
比如定义了一个模板函数compare

template<typename T> 
int compare(const T &v1, const T &v2)

使用时,如果这样用

compare(1, 0)

就相当于instance化了一个特定版本的函数,T绑定了int。

声明为inline或者constexpr的,inline这个关键字要放在模板参数列表之后,返回类型之前,如下

template <typename T> inline T min(const T&, const T&)

类型参数前必须使用关键字class 或 typename, 可以看到上面都用的是typename,
也可以用

template <class T>

因为typename是在模板已经广泛使用之后才引入cpp语言中的,所以一些程序员仍然只用class

每个类型参数前必须使用class 或者 typename, 下面这样做是不对的

template <typename T, U>  //这样不对,U前也必须用typename 或 class

说下模板的编译:

编译器遇到一个模板定义时,并不生成代码,只有当实例化时才会生成代码。
大多数编译错误是在实例化期间报告的
第 1 阶段编译模板本身时,会检查语法错误,比如忘记分号。
第 2 阶段 编译器遇到模板使用时,对函数模板的调用,会检查实参数目是否正确。
第 3 阶段实例化时,只有这个阶段才能发现类型相关的错误,这类错误可能在link时才报告。

类模板

类模板也是以关键字template开始,后面跟模板参数列表

template <typename T> class Blob {
    ...
};

这里要说下阅读模板类代码时,要记住类模板的名字不是一个类型名,比如

template<class SEMANTICS>
bool SemanticsOcTreeNode<SEMANTICS>::isSemanticsSet() const
{
  return this->semantics.isSemanticsSet();
}

SEMANTICS semantics;

可以看到isSemanticsSet函数是semantics对象的函数,但是要知道SEMANTICS并不是一个类型名,它具体是什么类型,要看调用它的地方传的是什么实参类型。

和其他类相同,既可以在类模板内部,也可以在类模板外部定义其成员函数。
且定义在类模板内的成员函数被隐式声明为inline函数

为了生成一个实例化版本,编译器需要掌握函数模板或类模板成员函数的定义,因此,函数模板和类模板成员函数的定义通常放在头文件中。

在类模板自己的作用域中,可以直接使用模板名而不提供实参,如下

template <typename T> class B {
   ...
   B& operator++();  //这里不需要指定B<T>
};

但是,当定义在类模板外时,就要加上

friend class

如果模板类包含一个非模板friend class, 那么友元被授权可以访问所有模板实例,
如果友元自身是模板,类可以授权给所有友元模板实例,也可以只授权给特定实例。
具体下次再码。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值