Considere este código:
#include <vector>
#include <iostream>
enum class A
{
X, Y
};
struct Test
{
Test(const std::vector<double>&, const std::vector<int>& = {}, A = A::X)
{ std::cout << "vector overload" << std::endl; }
Test(const std::vector<double>&, int, A = A::X)
{ std::cout << "int overload" << std::endl; }
};
int main()
{
std::vector<double> v;
Test t1(v);
Test t2(v, {}, A::X);
}
Isso imprime:
vector overload
int overload
Por que isso não produz um erro de compilação devido à resolução ambígua de sobrecarga? Se o segundo construtor for removido, obteremos vector overloadduas vezes. Como / por qual métrica é intuma correspondência inequivocamente melhor do {}que std::vector<int>?
A assinatura do construtor certamente pode ser melhorada, mas acabei de ser enganado por um trecho de código equivalente e quero garantir que nada de importante seja perdido para esta pergunta.
{}efetivamente faz em certos casos especiais, mas geralmente não é correto (para iniciantes, std::vector<int> x = {};funciona, std::vector <int> x = 0;não). Não é tão simples como " {}atribui zero".
struct A { int x = 5; }; A a = {};não atribui zero em nenhum sentido, ele constrói um Acom a.x = 5. Isso é diferente A a = { 0 };, que inicializa a.xcomo 0. O zero não é inerente {}, é inerente à forma como cada tipo é construído por padrão ou inicializado por valor. Veja aqui , aqui e aqui .
{}como um bloco de código, atribui 0 a variáveis - exemplo: const char x = {}; é definido como 0 (caractere nulo), o mesmo para int etc.