O código a seguir é impresso nullptr
em vez de empty
( godbolt 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({});
}
Desativar a f(nullptr_t)
variante faz com empty
que ela seja impressa. Quais são as regras que o C++ está usando para selecionar a nullptr_t
variante sobre a empty
variante quando ambas estão disponíveis?
A inicialização
std::nullptr_t
(ou qualquer outro tipo fundamental){}
é melhor porque resulta em uma conversão de identidade, enquanto a inicialização de tipos de classe resulta em uma sequência de conversão definida pelo usuário:- [over.ics.list] p8
empty
é um tipo agregado, portanto este parágrafo se aplica.std::nullptr_t
não é uma classe, então o seguinte parágrafo se aplica:- [over.ics.list] p10
[over.best.ics] explica qual sequência de conversão implícita é melhor, mas deve ser óbvio que uma conversão de identidade supera todo o resto.