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; …
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
?
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 claseagg_t2
con un constructor proporcionado por el usuario. También define dos funcionesconstexpr
,ce1
yce2
, que toman objetos de tipoagg_t1
yagg_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ónconstexpr
.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 utilizaragg_t2
como parámetro en la definición de una funciónconstexpr
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ónconstexpr
.