7.2 显式模板类型,显式模板实例化与隐式类型转换
对于模板中的任何显式类型部分,其都遵循隐式类型转换规则 。这主要分为两种情况:
1. 显式类型形参
参考以下代码:
template <int = 0>void test(int) {}int main{test(0.); // double -> int}上述代码中,虽然test是模板函数,但其第一参数是一个明确的int类型,故传入的double类型实参将通过隐式类型转换被转换为int类型 。
2. 显式模板实例化
参考以下代码:
template <typename T>void test(T) {}int main{test<int>(0.); // 强制调用void test(int)版本,double -> int}上述代码中,我们通过显式模板实例化,强行构造并调用了一个void test(int)版本的函数 。则此时,实参的double类型将通过隐式类型转换被转换为int类型 。
7.3 引用折叠
引用折叠是另一种较为复杂的类型转换 。参考以下代码:
template <typename T>void test(T &) {}template <typename T>void test(T &&) {}int main{const int &a = 0;const int &&b = 0;test(a); // 调用void test(int & &) -> 折叠为void test(int &)test(b); // 调用void test(int && &) -> 折叠为void test(int &)test(std::move(a)); // 调用void test(int & &&) -> 折叠为void test(int &)test(std::move(b)); // 调用void test(int && &&) -> 折叠为void test(int &&)}当模板参数声明为一个引用,且调用参数也为一个引用时,模板实例化出的参数类型将出现“引用的引用”,这包括以下四种情况:
- 使用T &调用T &:T & &
- 使用T &&调用T &:T && &
- 使用T &调用T &&:T & &&
- 使用T &&调用T &&:T && &&
需要注意的是,引用折叠只是对实参的适配手段,并不改变T的类型 。即:如果使用T &调用T &&,则T的类型就是T & 。
3.函数模板的重载确定
对于模板重载,首先需要明确以下几个要点:
- 模板也可以重载,各模板函数之间的函数签名应互不相同
- 模板函数与非模板函数可并存,共同作为同一重载体系
- 模板特化隶属于某个模板函数的强制实例化版本,与函数重载无关(重载确定后,如果确实调用了具有模板特化的模板函数,此时才会考虑模板特化)
- 精确匹配的非模板函数的优先级大于有能力通过实例化得到精确匹配的模板函数
- 普适性更低的模板函数的优先级大于普适性更高的模板函数
template <typename T>void test(T) {}template <>void test(double) {}template <typename T>void test(T, T) {}template <>void test(int, int) {}void test(double) {}void test(int, double) {}int main{test(0.); // 调用非模板函数void test(double)test(0, 0.); // 调用非模板函数void test(int, double)test(0); // 调用void test(T)实例化得到的void test(int)test(0, 0); // 调用void test(T, T)的特化版本void test(int, int)}上述代码中,我们为test函数定义了4个重载版本,包括两个模板函数以及两个非模板函数,此外,我们还定义了两个模板特化函数,下面分别讨论对test函数的四种调用情况:1. test(0.)
对于此调用,候选函数包括:
- void test(T)模板函数(其有能力实例化出一个精确匹配的void test(double),但这不于重载确定阶段考虑)
- void test(double)非模板函数
2. test(0, 0.)
与test(0.)的情况类似,虽然模板函数void test(T, T)能够实例化出一个精确匹配的void test(int, double)版本,但由于存在一个精确匹配的非模板函数函数,编译器将选择此版本 。
3. test(0)
对于此调用,候选函数包括:
- void test(T)模板函数,其有能力实例化出精确匹配版本void test(int)
推荐阅读
- 隔夜的小葱可以吃吗 沙葱隔夜能吃吗
- 全遮光的窗帘对睡眠好吗 窗帘不遮光睡觉对眼睛有害吗
- MySQL如何选择合适的索引
- 支付系统整体架构详解
- 去世一周年上坟有什么讲究 去世的人第一个清明节上坟吗
- Apache ShardingSphere开源的分布式数据库中间件
- 微信拓客的七个步骤与话术
- 创意好文案的7个套路
- 一网打尽光纤配件,弱电最全的光纤配件
- POE供电七个问题
