【发布时间】:2021-12-28 04:52:08
【问题描述】:
这是我的代码:
class agg_t1{
int x; // private non-static data menber
};
class agg_t2{
agg_t2(){} // user-provided constructor
};
constexpr void ce1(agg_t1 arg){}; // OK
constexpr void ce2(agg_t2 arg){}; // ERROR: parameter type 'agg_t2' is not a literal type
constexpr 函数的定义应满足以下要求:...
- 它的每个参数类型都应该是一个文字类型; ...
一个类型是文字类型,如果它是:...
- 它可以是闭包类型、聚合类型,或者...
我理解agg_t2 不是文字类型的原因是它违反了dcl.init.aggr#1.1 的规则:
聚合是一个数组或一个类...
- 没有用户声明或继承的构造函数...
我认为agg_t1 可能不是文字类型,因为它也违反了规则dcl.init.aggr#1.1:
聚合是一个数组或一个类...
- 没有私有或受保护的直接非静态数据成员...
但是...compiler result 告诉我我对 agg_t1 的假设是错误的。
我的问题是:
如果agg_t1的私有数据成员x使其成为非聚合类型,那么为什么constexpr的ce1的函数定义中允许agg_t1类型?
【问题讨论】:
-
在什么类型是文字类型的定义中,“聚合类型”之后有一些词。这些话可能很重要。
-
您的论点是
agg_t1和agg_t2都不是聚合,尽管它们的名称是经过巧妙选择的。您尚未消除它们可能是文字类型的其他可能性(闭包类型以及您在“或”之后切断的任何内容 - 与“或”运算符一样,证明||的一个操作数为假并不使整个表达式为假。) -
"...或至少有一个 constexpr 构造函数或构造函数模板(可能继承...)不是复制或移动构造函数,"
-
or 之后的那部分:“... or 至少有一个 constexpr 构造函数或构造函数模板”。碰巧
agg_t1的隐式声明的默认构造函数是constexpr,根据[class.default.ctor]/4 -
添加
-std=c++20开关,然后你的测试compiles。
标签: c++ language-lawyer constexpr constant-expression constexpr-function