C++ Primer 5th笔记(chap 16 模板和泛型编程)模板实参推断

Posted thefist11

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ Primer 5th笔记(chap 16 模板和泛型编程)模板实参推断相关的知识,希望对你有一定的参考价值。

1. 模板实参推断( template argument deduction)

在模板实参推断过程中, 编译器使用函数调用中的实参类型来寻找模板实参, 用这些模板实参生成的函数版本与给定的函数调用最为匹配。

1.1 实参类型转换

如果一个函数形参的类型使用了模板类型参数, 那么它采用特殊的初始化规则。 类型转换:

  • const转换。可以将一个非const对象的指针或者引用传递给一个const指针或者引用形参。
  • 数组或函数指针转换,如果函数形参不是引用类型,则可以对数组或者函数类型的实参应用正常的指针转换

但是

  • 编译器通常不是对实参进行类型转换,而是生成一个新的模板实例。
  • 其他的类型转换,如算术转换,派生类向基类的转换,以及用户自定义的转换,都不能应用于函数模板的实参。
template <typename T> T fobj(T, T);//实参是被拷贝
template <typename T> T fref(const T &, const T &);//引用

string s1("a value");
const string s2("another value");
fobl(s1, s2);//调用fobj(string ,string);忽略顶层const

fref(s1, s2);//调用的是,fref(const string &, const string &), s1转换为const是允许的。

int a[10], b[30];
fobj(a, b);//调用的是,fobj(int *, int *)
fref(a, b);//错误,数组的类型不一致。 

1.2 使用相同模板参数类型的函数形参

一个模板类型参数可以用作多个函数形参的类型。 由于只允许有限的几种类型转换,因此传递给这些形参的实参必须具有相同的类型。 如果推断出的类型不匹配, 则调用就是错误的。

eg, compare 函数接受两个 const T &参数, 其实参必须是相同类型:
long lng;
compare (lng, 1024 ); / / 错误: 不能实例化 compare (long, int )
  • 解决方法:将函数模板定义为两个类型参数:
//实参类型可以不同, 但必须兼容
template ctypename A, typename B> int flexibleCompare (const A& vl, const B& v2){
    if (vl < v2) return -1;
    if (v2 < vl) return 1/
    return 0;
} 

long lng;
flexibleCompare (lng, 1024 ); / / 正确: 调用 flexibleCompare (long, int )

1.3 正常类型转换应用于普通函数实参

函数模板可以有用普通类型定义的参数, 即, 不涉及模板类型参数的类型。 这种函数实参不进行特殊处理; 它们正常转换为对应形参的类型。

eg.

template <typename T> ostream Sprint (ostream &os, const T &obj )
{
   return os « obj;
}

print (cout, 42 ); // 实例化 print (ostream&, int )
ofstream f ("output" );
print (f, 10); // 使用 print (ostream&, int ) ; 将 f 转换为 ostream&

以上是关于C++ Primer 5th笔记(chap 16 模板和泛型编程)模板实参推断的主要内容,如果未能解决你的问题,请参考以下文章

C++ Primer 5th笔记(chap 16 模板和泛型编程)std::move

C++ Primer 5th笔记(chap 16 模板和泛型编程)模板特例化

C++ Primer 5th笔记(chap 16 模板和泛型编程)类模板特例化

C++ Primer 5th笔记(chap 16 模板和泛型编程)实例化

C++ Primer 5th笔记(chap 16 模板和泛型编程)可变参数模板

C++ Primer 5th笔记(chap 16 模板和泛型编程)模板实参