tox*_*xic 28 c++ templates function-templates overload-resolution template-argument-deduction
在下面的示例中,0
它以一种特殊的方式运行:它选择与示例函数调用所期望的不同的重载。我想知道为什么。我的理解也如下。
#include <iostream>
template<typename T>
void f(T a) {
std::cout << "first" << std::endl;
}
template<typename T>
void f(T* a) {
std::cout << "second" << std::endl;
}
int main()
{
f(0);
f<size_t>(0);
f<size_t>(0UL);
f(1);
f<size_t>(1);
}
Run Code Online (Sandbox Code Playgroud)
输出:
first
second
first
first
first
Run Code Online (Sandbox Code Playgroud)
我的理解:
f(0)
- 模板参数推导,整数文字0
是int
类型,因此f
选择第一个T=int
f<size_t>(0)
-带有整数提升的显式模板实例化,选择的类型是T=size_t
,选择第一个函数并从到提升0
(我在这里错了)int
size_t
f<size_t>(0UL)
- 与上面相同,但没有升级(0 已经是 type size_t
)
f(1)
- 与 1 相同。
f<size_t>(1)
- 与2相同。(我因为某种原因在这里??)
笔记:
我知道它0
可以隐式转换为空指针:
空指针常量是一个值为 0 的整数文字 (5.13.2) 或 std::nullptr_t 类型的纯右值
不过,我从标准中也知道,推广的优先级高于转化:
每种类型的标准转换序列都被分配以下三个等级之一:
- 精确匹配:无需转换、左值到右值转换、限定转换、函数指针转换、(C++17 起)用户定义的类类型到同一类的转换
- 促销方式:积分促销、浮点促销
- 转换:整数转换、浮点转换、浮点积分转换、指针转换、指针到成员转换、布尔转换、派生类到其基类的用户定义转换
use*_*570 27
f<size_t>(0)
- 具有整数提升的显式模板实例化,选择类型为T=size_t
,选择第一个函数,并将 0 从 int 提升为size_t
f<size_t>(0)
调用/使用第二个重载的原因f(T*)
是因为部分排序规则。特别地,第二个重载比第一个重载f(T* a)
更专门f(T a)
。
请注意,如果我们使用普通(非模板)函数,void f(std::size_t*)
那么void f(std::size_t)
调用f(0)
将是不明确的,但使用函数模板(如您的情况),调用更f(0)
喜欢/选择void f(T*)
版本,因为它比void f(T)
为什么
f(0)
调用第一个重载。我知道 0 可以隐式转换为空指针:
因为模板参数推导时不考虑隐式转换。这意味着对于调用来说,f(0)
只有第一个重载void f(T a)
是可行的。换句话说,第二次重载void f(T* a)
对于调用来说甚至不可行f(0)
。您可以在此演示中验证这一点:
template<typename T>
void f(T* a) {
std::cout << "second" << std::endl;
}
int main()
{
f(0);//FAILS because implicit conversion are not considered during deduction
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1404 次 |
最近记录: |