为什么 C++ 解析为这个函数而不是那个函数?

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

以下代码打印

nullptr
而不是预期的
empty
godbolt 链接):

#include <iostream>

class empty { };

#if 1
void f(std::nullptr_t) {
    std::cout << "nullptr\n";
}
#endif

void f(empty) {
    std::cout << "empty\n";
}

int main() {
    f({});
}

禁用

f(nullptr_t)
变体会导致按预期打印
empty
。当两者都可用时,C++ 使用什么规则来选择
nullptr_t
变体而不是
empty
变体?

c++ gcc clang overload-resolution nullptr
1个回答
3
投票

使用

std::nullptr_t
初始化
{}
(或任何其他基本类型)会更好,因为它会导致身份转换,而初始化类类型会导致用户定义的转换序列:

否则,如果参数具有可以根据聚合初始化规则([dcl.init.aggr])从初始化器列表初始化的聚合类型,则 隐式转换序列是用户定义的转换序列,其第二个标准转换序列是身份转换。

- [over.ics.list] p8

empty
是聚合类型,因此本段适用。

否则,如果参数类型不是类:

  • (10.1) [...]
  • (10.2) 如果初始值设定项列表没有元素,则 隐式转换序列是恒等转换。
  • [...]

- [over.ics.list] p10

[over.best.ics] 解释了哪种隐式转换序列更好,但很明显,身份转换胜过其他一切。

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