Ser um tipo de POD exatamente equivalente a ser um tipo trivial de layout padrão?

22

No C ++ 20, o conceito de POD foi descontinuado, supostamente porque é uma característica composta sem sentido de ser trivial e com layout padrão. No entanto, a definição de POD no rascunho do C ++ 20 não é exatamente "tanto trivial quanto com layout padrão"; é realmente:

Uma classe POD é uma classe que é tanto uma classe trivial quanto uma classe de layout padrão e não possui membros de dados não estáticos do tipo não-POD (ou sua matriz). Um tipo de POD é um tipo escalar, uma classe de POD, uma matriz desse tipo ou uma versão qualificada para CV de um desses tipos.

Em outras palavras, não apenas um tipo de POD é de layout trivial e padrão, mas também é recursivamente.

Esse requisito recursivo é redundante? Em outras palavras, se um tipo é trivial e de layout padrão, é automaticamente recursivamente trivial e de layout padrão também? Se a resposta for "não", qual é o exemplo de um tipo trivial de layout padrão que falha em ser POD?

Brian
fonte

Respostas:

12

No C ++ 20, o conceito de POD foi descontinuado, supostamente porque é uma característica composta sem sentido de ser trivial e com layout padrão.

Incorreta. O termo POD está sendo preterido porque não importa mais :

O termo POD não serve mais a um propósito do padrão, é apenas definido e as restrições se aplicam quando alguns outros tipos preservam essa propriedade vestigial.

Essencialmente, um tipo de layout trivial e padrão não ganha nenhuma habilidade além do que é trivial e o layout padrão fornece por conta própria. A combinação dos dois não torna o tipo especial e as duas propriedades não têm muito a ver uma com a outra.

O layout padrão é sobre o layout de seus subobjetos não vazios que estão sendo bem definidos (assim como seus subobjetos de classe base vazios, que não perturbam o layout do tipo). Trivialidade é sobre se o objeto tem algum significado além do bloco de bits que armazena (e se é conceitualmente um objeto válido se for inicializado com um bloco arbitrário de bits).

Se estou criando um modelo que usa um tipo Te quero ver se consigo memcpyobjetos desse tipo, não me importo com o layout de seus membros; Quero saber se é TriviallyCopyable. Da mesma forma, a correção de offsetofnão se importa nem um pouco se a classe tiver um construtor de cópias fornecido pelo usuário. Tudo o que importa é se o layout dos subobjetos dos membros ocorrer em uma ordem clara e aplicada por padrão.

Basicamente, as pessoas olharam em volta e perceberam que não havia mais nada em C ++ que precisasse especificamente da interseção de trivialidade e layout padrão. Portanto, não precisamos reservar um prazo para isso. Os poucos locais em que o padrão declara expressamente que algum tipo será "POD" podem ser simplesmente substituídos por "layout trivial e padrão", conforme apropriado.

Esse requisito recursivo é redundante?

Como os dois requisitos constituintes são recursivos individualmente, a interseção dos dois também é recursiva. Portanto, não há necessidade explícita de afirmar que todos os subobjetos também são POD. Isso foi mais do que provável apenas um caso de uma estranheza de copiar e colar, em que a definição original dizia algo como "todos os membros de dados não estáticos devem ser do tipo POD" e eles mantiveram essa declaração como está.

Nicol Bolas
fonte
" Tudo o que importa é se o layout dos subobjetos dos membros ocorrer em uma ordem clara e aplicada por padrão ". Por que o std precisaria fazer cumprir uma ordem para poder determinar o deslocamento de um membro? É um objetivo do std permitir impl loucos onde os membros não têm um deslocamento?
precisa
1

O layout padrão depende do layout padrão de membros não estáticos:

[class.prop]

Uma classe S é uma classe de layout padrão se:

  • não possui membros de dados não estáticos do tipo classe de layout não padrão (ou matriz de tais tipos) ou referência,

  • ...

A trivialidade também depende da trivialidade de membros não estáticos. Por uma questão de concisão, citei apenas a regra para o construtor padrão, mas as outras funções-membro especiais têm palavras semelhantes:

[class.default.ctor]

Um construtor padrão é trivial se não for fornecido pelo usuário e se:

  • ...
  • para todos os membros de dados não estáticos de sua classe que são do tipo de classe (ou matriz dos mesmos), cada uma dessas classes possui um destruidor trivial.

Tanto quanto posso dizer, o requisito explícito do PODness de aplicar aos membros é redundante, pois também implica implicitamente os requisitos de layout padrão e trivial.

eerorika
fonte