【语法】模板

  • 泛型代码两个原则:

    1 模板中函数参数是const的引用:保证函数可用于不能拷贝的类型
    2 函数体只是用<比较运算


  • 类型模板参数:
template<typename T> inline bool compare(const T& lhs, const T& rhs)
{
    return lhs < rhs;
}

  • 非类型模板参数:
template<unsigned N> inline int back(const int (&lhs)[N])
{
    return lhs[N - 1];
}

int main()
{
    const int a[2]{1, 2};
    cout<<back(a);
    return 0;
}

1 数组作为非引用参数会被退化为指针,无法推导出N,需要使用引用保持数组类型

注意区别引用的数组

bool back(int &lhs[2])//非法

数组的引用

bool back(int (&lhs)[2])

2 inline说明符放在模板参数列表之后


  • 模板编译:

编译器遇到模板定义时,并不生成代码。只有当实例化出模板的特定版本时,编译器才会生成代码,为了生成一个实例化版本,编译器需要掌握函数模板或类模板的成员函数的定义。因此,模板的头文件包含声明和定义。函数模板和类模板的成员函数定义放在头文件中。


  • 类模板

函数模板可以推导参数类型,类模板不可以,需要额外提供信息

template<typename T> 
class Blob
{
private:
    vector<T> vec;
public:
    void func(const T& lhs);
};

template<typename T> 
void Blob<T>::func(const T& lhs)
{
    vec.push_back(lhs);
}

int main()
{
    Blob<int> b;
    b.func(2);
    return 0;
}

使用类模板类型时必须提供模板参数,
在类模板自己的作用域中,可以直接使用模板名而不提供实参,
在类外定义成员时,直到遇到类名::才算进入类作用域

template<typename T>
Blob<T> Blob<T>::operator++(int lhs)
{
    Blob ret = *this;
    return ret;
}

  • 使用类的类型成员

默认情况下,作用域运算符访问的是名字,不是类型。使用typename显示告诉编译器访问的是类型。

template <typename T>
typename T::value_type top(const T& c)
{
    return typename T::value_type();
}

  • 模板成员函数:

模板成员函数不能是虚函数

template<typename T>
template<typename It>
Blob <T>::Blob(It b, It e)
{
    vec.insert(vec.begin(), b, e);
}

类模板外定义成员模板函数时,必须同时为类和成员模板提供模板参数列表,编译器根据实参推断模板成员函数的参数类型。


  • 控制实例化

当两个或者多个独立编译的源文件使用了相同的模板,并提供了相同的模板参数,每个文件都会有改模板的一个实例。
通过显示的实例化避免开销

A文件:

extern template class Blob<string>; //实例化声明
Blob<string> s1;//实例化在其他文件

B文件:

template class Blob<sting>;//实例化定义

将一个实例化声明为extern就表示承诺在程序的其他位置有该实例化的非extern声明(定义)。

与普通实例化不同,实例化定义会实例化所有成员
普通情况下,类模板的成员函数只有当程序用到它时才会实例化。


  • 函数模板显式实参
template<typename T1,typename T2,typename T3>
T1 sum(T2, T3);

auto func = sum<long>(i,j)

特别是当返回类型与函数参数列表中的所有类型不一致时,需要显式指出返回类型。

为了不显式实参,可以使用尾置返回类型

template<typename It>
auto func(It begin, It end)->decltype(*begin)
{
    return *begin;
}

解引用返回左值,decltype推断的类型为begin所指元素类型的引用

若只要返回值,不返回引用,可使用类型转换模板进行类型转换


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值