Czy bycie typem POD jest dokładnie równoważne byciu banalnym typem standardowego układu?

22

W C ++ 20 koncepcja POD jest przestarzała, prawdopodobnie dlatego, że jest to bezsensowna złożona cecha bycia trywialnym i standardowym układem. Jednak definicja POD w wersji roboczej C ++ 20 nie jest dokładnie „zarówno trywialna, jak i standardowa”; to jest właściwie:

Klasa POD jest klasą, która jest zarówno klasą trywialną, jak i klasą o standardowym układzie i nie ma żadnych niestatycznych elementów danych typu non-POD class (lub jej macierzy). Typ POD jest typem skalarnym, klasą POD, tablicą takiego typu lub wersją jednego z tych typów kwalifikowaną do CV.

Innymi słowy, nie tylko typ POD jest zarówno trywialny, jak i standardowy, ale także rekurencyjnie.

Czy to wymaganie rekurencyjne jest zbędne? Innymi słowy, jeśli typ jest zarówno trywialny, jak i standardowy, to czy automatycznie jest również rekurencyjnie trywialny i standardowy? Jeśli odpowiedź brzmi „nie”, to jaki jest przykład trywialnego typu standardowego układu, który nie jest POD?

Brian
źródło

Odpowiedzi:

12

W C ++ 20 koncepcja POD jest przestarzała, prawdopodobnie dlatego, że jest to bezsensowna złożona cecha bycia trywialnym i standardowym układem.

Błędny. Termin POD jest przestarzały, ponieważ nie ma już znaczenia :

Termin POD nie służy już celowi w normie, jest jedynie zdefiniowany, a ograniczenia obowiązują, gdy kilka innych typów zachowuje tę szczątkową właściwość.

Zasadniczo typ, który jest zarówno trywialny, jak i standardowy układ, nie zyskuje żadnych zdolności poza tym, co same w sobie są trywialne i standardowe. Połączenie dwóch nie czyni tego typu specjalnym, a te dwie właściwości tak naprawdę nie mają ze sobą wiele wspólnego.

Standardowy układ polega na tym, że układ niepustych podobiektów jest dobrze zdefiniowany (podobnie jak puste podobiekty klasy podstawowej nie zakłócają układu typu). Trywialność polega na tym, czy obiekt ma jakieś znaczenie poza blokiem bitów, które przechowuje (i czy jest koncepcyjnie poprawnym obiektem, jeśli jest inicjalizowany dowolnym blokiem bitów).

Jeśli tworzę szablon, który przyjmuje typ Ti chcę sprawdzić, czy mogę memcpytego typu obiekty, nie dbam o układ jego elementów; Chcę wiedzieć, czy można to zrobić TrivialCopyable. Podobnie poprawność offsetofnie ma najmniejszego znaczenia, jeśli klasa ma podany przez użytkownika konstruktor kopii. Chodzi tylko o to, czy układ podobiektów elementów odbywa się w przejrzystej, wymuszonej standardem kolejności.

Zasadniczo ludzie rozejrzeli się i zdali sobie sprawę, że w C ++ nie zostało nic, co wymagałoby przecięcia trywialności i standardowego układu. Nie musimy więc rezerwować terminu. Tych kilka miejsc, w których norma wyraźnie stwierdza, że ​​pewnym typem będzie „POD”, można po prostu zastąpić odpowiednio „trywialnym i standardowym układem”.

Czy to wymaganie rekurencyjne jest zbędne?

Ponieważ oba wymagania składowe są indywidualnie rekurencyjne, przecięcie tych dwóch również jest rekurencyjne. Nie ma więc wyraźnej potrzeby stwierdzania, że ​​wszystkie podobiekty są również POD. Był to więcej niż prawdopodobnie przypadek dziwności polegającej na kopiowaniu i wklejaniu, w której oryginalna definicja mówiła coś w stylu „wszyscy niestatyczni członkowie danych muszą być typami POD” i po prostu zachowali tę instrukcję w niezmienionej postaci.

Nicol Bolas
źródło
Chodzi o to, czy układ podobiektów elementów odbywa się w przejrzystej, standardowej kolejności ” Dlaczego standard miałby egzekwować polecenie, aby móc określić przesunięcie elementu? Czy celem std jest umożliwienie szalonego impl, gdy członkowie nie mają przesunięcia?
ciekawy,
1

Standardowy układ zależy od standardowego układu elementów niestatycznych:

[class.prop]

Klasa S jest klasą układu standardowego, jeżeli:

  • nie ma elementów danych niestatycznych typu niestandardowego typu układu (lub tablicy takich typów) lub odniesienia,

  • ...

Trywialność zależy również od trywialności członków niestatycznych. Dla zwięzłości podałem tylko regułę dla domyślnego konstruktora, ale inne specjalne funkcje składowe mają podobne sformułowanie:

[class.default.ctor]

Domyślny konstruktor jest trywialny, jeśli nie został udostępniony przez użytkownika i jeśli:

  • ...
  • dla wszystkich niestatycznych elementów danych swojej klasy, które są typu klasy (lub ich tablic), każda taka klasa ma trywialny destruktor.

O ile mogę powiedzieć, wyraźny wymóg PODness dotyczący zastosowania do członków jest zbędny, ponieważ domyślnie wynika również z wymagań dotyczących standardowego układu i trywialności.

eerorika
źródło