重载解析和模板参数推导 - 为什么 0 很特殊?

问题描述 投票:0回答:1

在下面的示例中,

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);
}

输出:

first
second
first
first
first

我的理解:

f(0)
- 模板参数推导,整数文字
0
int
类型,因此第一个
f
T=int

选择

f<size_t>(0)
- 使用整数提升显式模板实例化,选择类型为
T=size_t
,选择第一个函数,并且
0
int
size_t
升级
我错了

f<size_t>(0UL)
- 与上面相同,但没有促销(0 已经是类型
size_t

f(1)
- 与 1 相同。

f<size_t>(1)
- 与2相同。(我出于某种原因在这里??)

注意:

我知道

0
可以隐式转换为空指针:

空指针常量是一个值为 0 的整数文字 (5.13.2) 或 std::nullptr_t 类型的纯右值

但是,从标准中我也知道,推广比转化更优先:

每种类型的标准转换序列都分配有以下三种类型之一 排名:

  1. 精确匹配:无需转换,左值到右值 转换、限定转换、函数指针 conversion,(C++17 起)用户定义的类类型到 同班
  2. 促销:积分促销、浮点促销
  3. 转换:积分转换、浮点转换、 浮点积分转换、指针转换、成员指针 转换、布尔转换、派生的用户定义转换 类到其基础
c++ templates overload-resolution
1个回答
2
投票

f<size_t>(0)
- 具有整数提升的显式模板实例化,选择的类型是 T=size_t,选择第一个函数并将 0 从 int 提升到 size_t(我错了)j

f<size_t>(0)
调用/使用第二个重载
f(T*)
的原因是因为部分排序规则。特别是,第二个重载
f(T* a)
比第一个重载f(T a)
更专业

© www.soinside.com 2019 - 2024. All rights reserved.