fbr*_*eto 17 c++ gcc clang nullptr overload-resolution
以下代码打印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({});
}
Run Code Online (Sandbox Code Playgroud)
禁用f(nullptr_t)变体会导致empty打印。当两个变体都可用时,C++ 使用什么规则来选择nullptr_t变体?empty
Jan*_*tke 32
初始化std::nullptr_t(或任何其他基本类型){}更好,因为它会导致身份转换,而初始化类类型会导致用户定义的转换序列:
否则,如果参数具有可以根据聚合初始化规则([dcl.init.aggr])从初始化器列表初始化的聚合类型,则隐式转换序列是用户定义的转换序列,其第二个标准转换序列是一种身份转换。
empty是聚合类型,因此本段适用。std::nullptr_t不是一个类,因此以下段落适用:
否则,如果参数类型不是类:
- (10.1) [...]
- (10.2) 如果初始值设定项列表没有元素,则隐式转换序列是恒等转换。
- [...]
[over.best.ics]解释了哪种隐式转换序列更好,但很明显,恒等转换胜过其他一切。