gcc 为什么重载解析在传递{}时优先使用std::nullptr_t而不是类?

pdsfdshx  于 6个月前  发布在  其他
关注(0)|答案(1)|浏览(47)

下面的代码打印nullptr而不是emptygodbolt link):

#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被打印。当empty变体和nullptr_t变体都可用时,C++使用什么规则来选择nullptr_t变体而不是empty变体?

tez616oj

tez616oj1#

{}初始化std::nullptr_t(或任何其他基本类型)更好,因为它会导致标识转换,而初始化类类型会导致用户定义的转换序列:
否则,如果参数的聚合类型可以根据聚合初始化规则([dcl.init.aggr])从初始化器列表中初始化,则隐式转换序列是用户定义的转换序列,其第二个标准转换序列是单位转换。

  • [over.ics.list] p8
    empty是一个聚合类型,所以这一段适用。std::nullptr_t不是一个类,所以下面的段落适用:
    否则,如果参数类型不是类:
  • (10.1)[.]
  • (10.2)如果初始化器列表没有元素,隐式转换序列是恒等转换。
  • [...]
  • [over.ics.list] p10
    over.best.ics(https://eel.is/c++draft/over.best.ics)解释了哪种隐式转换序列更好,但很明显,标识转换优于其他转换。

相关问题