Uważam, że zasadniczo sprowadzają się one do [temp.inst] / 2 ( wyróżnienie moje):
Domniemana instancji o specjalizacji klasa szablonu powoduje niejawne konkretyzacji deklaracji, ale nie z definicji , domyślnych argumentów lub noexcept-specyfikatorami tych funkcji składowych klasy, klas członkowskich, scoped wyliczeń członkowskich, statycznymi członkami danych , szablony członkowskich, a przyjaciele; […]
i [temp.inst] / 9
Implementacja nie może domyślnie tworzyć instancji […] statycznego elementu danych szablonu klasy […], chyba że taka instancja jest wymagana.
Sformułowanie w standardzie dotyczące domyślnej instancji szablonu pozostawia wiele szczegółów do interpretacji. Ogólnie wydaje mi się, że po prostu nie można polegać na tym, że części szablonu nie są tworzone, chyba że specyfikacja wyraźnie to mówi. A zatem:
Fragment nr 1
P: Dlaczego ten kod się kompiluje? Czy nie dziedziczymy A, gdy dziedziczymy po B? W B nie ma VD, więc czy kompilator nie powinien tutaj zgłaszać błędu?
Tworzysz instancję A<B>
. Ale tworzenie instancji A<B>
tylko tworzy deklaracje, a nie definicje elementów danych statycznych. VB
nigdy nie jest używany w sposób, który wymagałby definicji. Kompilator powinien zaakceptować ten kod.
Fragment nr 2
P: Dlaczego kompiluje się z gcc9 / dlaczego nie kompiluje się z clang9?
Jak wskazał Jarod42, deklaracja AB
zawiera typ zastępczy. Wydaje mi się, że brzmienie standardu nie jest do końca jasne, co ma się tu wydarzyć. Czy utworzenie wystąpienia deklaracji statycznego elementu danych zawierającego typ symbolu zastępczego wywołuje odliczenie typu symbolu zastępczego, a zatem stanowi zastosowanie wymagające definicji elementu danych statycznych? Nie mogę znaleźć sformułowania w standardzie, które jednoznacznie powiedziałoby na to „tak” lub „nie”. Tak więc powiedziałbym, że obie interpretacje są tutaj równie ważne, a zatem GCC i clang mają rację…
Fragment nr 3
P: Jeśli struktura B jest tutaj niekompletna, to dlaczego nie jest niekompletna we fragmencie nr 2?
Typ klasy jest kompletny tylko w punkcie, w którym osiągniesz zamknięcie }
specyfikatora klasy [class.mem] / 6 . W związku z tym B
jest niekompletny podczas domyślnej instancji A<B>
wszystkich fragmentów kodu. Po prostu było to nieistotne dla Snippet # 1. W Snippet # 2 clang spowodował błąd No member named AD in B
. Podobnie jak w przypadku fragmentu nr 2, nie mogę znaleźć sformułowania, w którym wystąpiłaby dokładnie instancja deklaracji aliasu członka. Jednak w przeciwieństwie do definicji statycznych elementów danych, nie ma sformułowania, które wyraźnie zapobiegałoby tworzeniu instancji deklaracji aliasu elementów podczas niejawnej instancji szablonu klasy. Powiedziałbym zatem, że zachowanie zarówno GCC, jak i clang jest prawidłową interpretacją standardu w tym przypadku…
struct B
instancjiA
zB
?