Considera 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);
}
Esto imprime:
vector overload
int overload
¿Por qué esto no produce un error de compilación debido a una resolución de sobrecarga ambigua? Si se elimina el segundo constructor, obtenemos vector overload
dos veces. ¿Cómo / por qué métrica es int
una combinación inequívocamente mejor {}
que std::vector<int>
?
La firma del constructor seguramente se puede recortar aún más, pero acabo de engañarme con un código equivalente y quiero asegurarme de que no se pierda nada importante para esta pregunta.
{}
efectivamente hace en ciertos casos especiales, pero generalmente no es correcto (para empezar, std::vector<int> x = {};
funciona, std::vector <int> x = 0;
no lo hace). No es tan simple como " {}
asigna cero".
struct A { int x = 5; }; A a = {};
no asigna cero en ningún sentido, construye un A
con a.x = 5
. Esto es diferente A a = { 0 };
, que se inicializa a.x
a 0. El cero no es inherente a {}
, es inherente a cómo cada tipo se construye por defecto o se inicializa en valor. Mira aquí , aquí y aquí .
{}
como un bloque de código, asigna 0 a las variables - ejemplo: const char x = {}; se establece en 0 (null char), lo mismo para int etc.