¿Ser un tipo de POD es exactamente equivalente a ser un tipo trivial de diseño estándar?

22

En C ++ 20, el concepto de POD está en desuso, supuestamente porque es un rasgo compuesto sin sentido de ser trivial y de diseño estándar. Sin embargo, la definición de POD en el borrador de C ++ 20 no es exactamente "diseño trivial y estándar"; en realidad es:

Una clase POD es una clase que es a la vez una clase trivial y una clase de diseño estándar, y no tiene miembros de datos no estáticos de tipo clase no POD (o matriz de los mismos). Un tipo POD es un tipo escalar, una clase POD, una matriz de ese tipo o una versión calificada por cv de uno de estos tipos.

En otras palabras, no solo es un tipo de POD tanto trivial como de diseño estándar, sino que también es recursivo.

¿Es este requisito recursivo redundante? En otras palabras, si un tipo es trivial y de diseño estándar, ¿también es automáticamente trivial y de diseño estándar recursivamente? Si la respuesta es "no", ¿cuál es un ejemplo de un tipo trivial de diseño estándar que no es POD?

Brian
fuente

Respuestas:

12

En C ++ 20, el concepto de POD está en desuso, supuestamente porque es un rasgo compuesto sin sentido de ser trivial y de diseño estándar.

Incorrecto. El término POD está en desuso porque ya no importa :

El término POD ya no cumple un propósito en el estándar, se define simplemente y se aplican restricciones cuando algunos otros tipos conservan esta propiedad vestigial.

Esencialmente, un tipo que es tanto trivial como de diseño estándar no adquiere ninguna habilidad más allá de lo que ser trivial y ser un diseño estándar proporciona por sí solo. La combinación de los dos no hace que el tipo sea especial, y las dos propiedades realmente no tienen mucho que ver entre sí.

El diseño estándar se refiere al diseño de sus subobjetos no vacíos bien definidos (así como a los subobjetos de clase base vacíos que no perturban el diseño del tipo). La trivialidad se trata de si el objeto tiene algún significado más allá del bloque de bits que almacena (y si es conceptualmente un objeto válido si se inicializa con un bloque arbitrario de bits).

Si estoy creando una plantilla que toma un tipo T, y quiero ver si puedo memcpyobjetos de ese tipo, no me importa el diseño de sus miembros; Quiero saber si es TriviallyCopyable. Del mismo modo, la corrección de offsetofno importa en lo más mínimo si la clase tiene un constructor de copia proporcionado por el usuario. Lo único que le importa es si el diseño de los subobjetos de miembros ocurre en un orden claro y de cumplimiento estándar.

Básicamente, la gente miró a su alrededor y se dio cuenta de que no queda nada en C ++ que necesite específicamente la intersección de la trivialidad y el diseño estándar. Por lo tanto, no necesitamos reservar un término para ello. Esos pocos lugares donde el estándar establece expresamente que algún tipo será "POD" puede simplemente ser reemplazado por "diseño trivial y estándar", según corresponda.

¿Es este requisito recursivo redundante?

Dado que ambos requisitos constituyentes son recursivos individualmente, la intersección de los dos también es recursiva. Por lo tanto, no hay necesidad explícita de indicar que todos los subobjetos también son POD. Esto era más que probable solo un caso de una rareza de copiar y pegar, donde la definición original decía algo así como "todos los miembros de datos no estáticos deben ser tipos POD" y simplemente mantuvieron esa declaración tal como está.

Nicol Bolas
fuente
"Lo único que le importa es si el diseño de los subobjetos de miembros ocurre en un orden claro y de cumplimiento estándar " ¿Por qué el estándar tendría que hacer cumplir un pedido para poder determinar el desplazamiento de un miembro? ¿Es un objetivo de la STD permitir implicaciones locas donde los miembros no tienen un desplazamiento?
curioso
1

La disposición estándar depende de la disposición estándar de los miembros no estáticos:

[class.prop]

Una clase S es una clase de diseño estándar si:

  • no tiene miembros de datos no estáticos de tipo clase de diseño no estándar (o matriz de tales tipos) o referencia,

  • ...

La trivialidad también depende de la trivialidad de los miembros no estáticos. Para ser concisos, he citado solo la regla para el constructor predeterminado, pero las otras funciones miembro especiales tienen una redacción similar:

[class.default.ctor]

Un constructor predeterminado es trivial si no es proporcionado por el usuario y si:

  • ...
  • para todos los miembros de datos no estáticos de su clase que son de tipo de clase (o matriz de los mismos), cada clase tiene un destructor trivial.

Por lo que puedo decir, el requisito explícito de PODness de aplicar a los miembros es redundante, ya que también se deduce implícitamente de los requisitos de ser un diseño estándar y trivial.

eerorika
fuente