模板与泛型学习二

本文深入探讨了C++中的模板实参推断,包括类型转换、函数模板显式实参、尾置返回类型、引用折叠以及std::move和转发的概念。通过实例解析了如何从函数实参推断模板参数,以及在不同情况下类型转换的规则。同时,介绍了std::move的作用和工作原理,以及在编写转发函数时的关键技巧。
摘要由CSDN通过智能技术生成

C++ Primer学习


从函数实参来确定模板实参的过程被称为模板实参推断。

模板实参推断

类型转换与模板类型参数

  1. const转换:可以将一个非const对象的引用(或指针)传递给一个const的引用(或指针)形参。顶层const无论是在形参中还是在实参中,都会被忽略。
  2. 数组或函数指针转换:函数形参不是引用类型。
  3. 一个模板类型参数可以用作多个函数形参的类型。

函数模板显式实参

  1. 显式模板实参按自左至右的顺序与对应的模板参数匹配。

尾置返回类型与类型转换

  1. 头文件type_traits中定义了类型转换模板。
template <typename T>
auto func(T begin,T end)->
typename remove_reference<decltype(*begin)>::type
{
	//处理...
	return *begin;
}

函数指针和实参推断

  1. 用一个函数模板初始化一个函数指针或为一个函数指针赋值时,编译器使用指针的类型来推断模板实参。
template <typename T> int compare(const T&,const T&);
//指针p所指函数中参数的类型决定T的模板实参的类型
int (*p)(const int&,const int&)=compare;
  1. 当参数是一个函数模板实例的地址时,程序上下文必须满足:对每个模板参数,能唯一确定其类型或值。
void func(int(*)(const string&,const string&));
void func(int(*)(const int&,const int&));
//可以通过显式模板实参来消除func调用的歧义
func(compare<int>);

模板实参推断和引用

  1. 编译器会应用正常的引用绑定规则;const时底层的,不是顶层的。
  2. T&:一个变量或一个返回引用类型的表达式。
  3. const T&:一个对象或一个临时量对象或是一个字面值常量值。这时T的类型推断结果不会是一个const类型。
  4. 两个例外规则:将一个左值传递给函数的右值引用参数,且此右值引用指向模板类型参数时,编译器推断模板参数为实参的左值引用类型;如果间接创建一个引用的引用,则这些引用形成了“折叠”。
template <typename T> void func(T&&);
int a=1;
//编译器推断T的类型为int&
func(a);
  1. 引用折叠只能应用于间接创建的引用的引用,如类型别名或模板参数。如果一个函数参数是指向模板参数类型的右值引用,则可以传递给它任意类型的实参。
  2. 右值引用通常用于两种情况:模板转发其实参或模板被重载。

理解std::move

  1. std::move
template <typename T>
typename remove_reference<T>::type&& move(T&& t)
{
	return static_cast<typename remove_reference<T>::type&&>(t);
}
  1. 虽然不能隐式地将一个左值转换为右值引用,但我们可以用static_cast显式地将一个左值转换为一个右值引用。

转发

某些函数需要将其一个或多个实参连同类型不变地转发给其他函数。

  1. 通过将一个函数参数定义为一个指向模板类型参数的右值引用,我们可以保持其对应实参的所有类型。而使用(无论是左值还是右值)引用参数使得可以保持const属性。
  2. forward必须通过显式模板实参来调用,forward可以保持给定实参的左值/右值属性,定义在头文件utility中。

术语

类型转换和模板类型参数

  1. 使用相同模板参数类型的函数形参
  2. 正常类型转换应用于普通函数实参

函数模板显式实参

  1. 指定显式模板实参
  2. 正常类型转换应用于显式指定的实参

尾置返回类型与类型转换

  1. 进行类型转换的标准库模板类

函数指针和实参推断

模板实参推断和引用

  1. 从左值引用函数参数推断类型
  2. 从右值引用函数参数推断类型
  3. 引用折叠和右值引用参数
  4. 编写接受右值引用参数的模板函数

理解std::move

  1. std::move是如何定义的
  2. std::move是如何工作的
  3. 从一个左值static_cast到一个右值引用是允许的

转发

  1. 定义能保持类型信息的函数参数
  2. 在调用中使用std::forward保持类型信息
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值