g++
daje ładny wyjaśnienie błędu:
bla.cpp:6:5: note: ‘D::D()’ is implicitly deleted because the default definition would be ill-formed: D() = default;
Domyślny konstruktor będzie próbował skonstruować wszystkie części D
. Nie masz żadnych pól, ale ma on początkową wartość B
- która nie ma pustego konstruktora, a tylko jeden: int
.
Domyślne zachowanie ma sens - D
nie powinien mieć pustego konstruktora, chyba że wyraźnie stwierdzono, który int
skonstruować B
z, a kompilator nie chce zgadywać. W przeciwnym razie będziesz mieć obiekt D
iw zależności od tego, co stanie się w konstruktorze B
może zawierać śmieci, na przykład podczas inicjowania pola.
Nie jestem pewien, czy chodziło o pytanie dosłownie jeśli zapytać, dlaczego jest to „dozwolone”, jak B
domyślny konstruktor zostanie usunięty, ale myślę, że z dwóch powodów:
- Ten zachowanie jest dobrze zdefiniowane i nie ma powodu, aby go odrzucać. Wykrywanie błędu tylko wtedy, gdy próbujesz coś nielegalnie skonstruować, i tak jest zrobione.
- Jest bardziej elastyczny - zmiana
B
na domyślny konstruktor automatycznie zezwala na D
.
Jeśli zmienisz B, D automatycznie zrobi to, co trzeba. –
Jakiego kompilatora używasz?Czy to możliwe, ponieważ twoja struktura jest pusta i nic nie robi, stąd kompilator pomija ją w całości zgodnie z definicją '= default'? –
g ++ 5.1.0 'uwaga: 'D :: D()' jest niejawnie usunięty, ponieważ domyślna definicja byłaby źle sformułowana:' i 'błąd: brak pasującej funkcji dla wywołania 'B :: B()'' –