es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El requisito para “Tipo Literal” en funciones “constexpr”.

Aquí está mi código:

class agg_t1{
    int x;      // miembro de datos no estático privado
};
class agg_t2{
    agg_t2(){}      // constructor proporcionado por el usuario
};
constexpr void ce1(agg_t1 arg){};       // OK
constexpr void ce2(agg_t2 arg){};       // ERROR: el tipo de parámetro 'agg_t2' no es un tipo literal

Según dcl.constexpr:

La definición de una función constexpr debe cumplir los siguientes requisitos: …
– cada uno de sus tipos de parámetro debe ser un tipo literal; …

Y basic#types.general-10:

Un tipo es un tipo literal si: …
– es un tipo de agregado, un tipo de cierre o …

Entiendo la razón por la cual agg_t2 no es un tipo literal, ya que viola la regla dcl.init.aggr#1.1:

Un agregado es una matriz o una clase con …
– no tiene constructores declarados por el usuario ni heredados …

Y creo que agg_t1 puede no ser un tipo literal porque también viola la regla dcl.init.aggr#1.2:

Un agregado es una matriz o una clase con …
– no tiene miembros de datos privados o protegidos directos no estáticos …

Sin embargo, el resultado del compilador me dice que estaba equivocado acerca de la suposición sobre agg_t1.

Mi pregunta es:

Si el miembro de datos privados x de agg_t1 lo convierte en un tipo no agregado, ¿por qué se permite el tipo agg_t1 en la definición de la función constexpr de ce1?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El fragmento de código proporcionado define una clase agg_t1 con un miembro de dato privado y no estático, y una clase agg_t2 con un constructor proporcionado por el usuario. También define dos funciones constexpr, ce1 y ce2, que toman objetos de tipo agg_t1 y agg_t2 como parámetros, respectivamente.

    Según el estándar de C++, un tipo literal es un tipo definido de tal manera que sus objetos pueden evaluarse en tiempo de compilación. Un tipo de agregado es un tipo que puede ser un tipo literal. Sin embargo, hay algunas restricciones en la definición de un tipo de agregado. Un tipo de agregado no debe tener ningún miembro de dato directo no estático privado o protegido, y no debe tener ningún constructor declarado por el usuario o heredado.

    En el código dado, agg_t1 es un tipo de agregado, a pesar de tener un miembro de dato privado no estático. Esto se debe a que, según dcl.init.aggr#1.1, un tipo de agregado puede tener miembros de dato directos no estáticos privados o protegidos, pero no se consideran al determinar si una clase es un tipo de agregado. Por lo tanto, agg_t1 sigue siendo considerado un tipo de agregado y, como tal, se puede utilizar como parámetro en la definición de una función constexpr.

    Por otro lado, agg_t2 no es un tipo de agregado porque tiene un constructor proporcionado por el usuario. Según dcl.init.aggr#1.1, un tipo de agregado no debe tener ningún constructor declarado por el usuario o heredado. Por lo tanto, intentar utilizar agg_t2 como parámetro en la definición de una función constexpr resulta en un error en tiempo de compilación.

    En resumen, el miembro de dato privado no estático de agg_t1 no descalifica a la clase como un tipo de agregado, y como tal, se puede utilizar como parámetro en la definición de una función constexpr.

Comments are closed.