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 overload
duas vezes. Como / por qual métrica é int
uma 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 A
com a.x = 5
. Isso é diferente A a = { 0 };
, que inicializa a.x
como 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.