Betrachten Sie diesen Code:
#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);
}
Dies druckt:
vector overload
int overload
Warum führt dies nicht zu einem Kompilierungsfehler aufgrund einer mehrdeutigen Überlastungsauflösung? Wenn der zweite Konstruktor entfernt wird, erhalten wir vector overload
zwei Mal. Wie / nach welcher Metrik passt int
eine eindeutig bessere Übereinstimmung {}
als std::vector<int>
?
Die Konstruktorsignatur kann sicherlich weiter gekürzt werden, aber ich wurde gerade von einem äquivalenten Code ausgetrickst und möchte sicherstellen, dass für diese Frage nichts Wichtiges verloren geht.
{}
in bestimmten Sonderfällen effektiv funktioniert, aber es ist im Allgemeinen nicht korrekt (für den Anfang, std::vector<int> x = {};
funktioniert, std::vector <int> x = 0;
funktioniert nicht). Es ist nicht so einfach wie " {}
Null zuweisen".
struct A { int x = 5; }; A a = {};
weist in keiner Weise Null zu, sondern erstellt eine A
mit a.x = 5
. Dies ist anders als A a = { 0 };
bei der Initialisierung a.x
auf 0. Die Null ist nicht inhärent {}
, sondern inhärent, wie jeder Typ standardmäßig konstruiert oder wertinitialisiert ist. Sehen Sie hier , hier und hier .
{}
als Codeblock erinnere , weist ich Variablen 0 zu - Beispiel: const char x = {}; wird auf 0 (null Zeichen) gesetzt, dasselbe gilt für int usw.