Kry*_*n S 14 c++ language-lawyer
该代码在所有4大编译器上都可以正常编译,即使在 -pedantic
struct S
{
constexpr S(int a) {}
};
constexpr int f(S a)
{
return 1;
}
int main()
{
int a = 0;
S s(a);
constexpr int b = f(s);
}
Run Code Online (Sandbox Code Playgroud)
但是,按照标准不应该这样...对吗?首先,s将无法在常量表达式 [expr.const] / 3中使用,因为它不满足成为constexpr,或,const以及枚举或整数类型的条件。
其次,它不是常量初始化的 [expr.const] / 2,因为由于对变量执行左值到右值转换,所以初始化的完整表达式不是常量表达式 [expr.const] / 10a) 在初始化构造函数的参数时不能在常量表达式中使用。
是否所有这些编译器都只是在省略构造函数参数的初始化,因为它没有副作用,并且是否符合标准(我99%的肯定不是,因为这样做的唯一方法是: make s constexpr,并将其传递const int给int声明的a 或a constexpr?
Sto*_*ica 10
我相信魔术师的s俩是的复制者S。您省略了它,因此在这里为您生成了默认值。现在它也是一个constexpr功能。
[class.copy.ctor](重点是我的)
12默认/未定义为删除的复制/移动构造函数在使用odr([basic.def.odr]), 需要进行常量评估([expr.const])或在以下情况时进行隐式定义:在首次声明后明确指定为默认值。[?注意:复制/移动构造函数是隐式定义的,即使实现取消了其odr-use([basic.def.odr],[class.temporary])。[?end note?] 如果隐式定义的构造函数可以满足constexpr构造函数([dcl.constexpr])的要求,则隐式定义的构造函数为constexpr。
副本c'tor的求值是否违反[expr.const] / 4中的任何要点?它不是。它不会在参数的任何成员上执行从左值到右值的转换(没有要对其执行转换)。它不会以任何要求引用在常量表达式中可用的方式使用其引用参数。因此,尽管不是直觉的,但我们确实得到了有效的常数表达式。
我们可以通过添加一个成员来验证以上内容S。
struct S
{
int a = 1;
constexpr S(int a) {}
};
Run Code Online (Sandbox Code Playgroud)
现在,副本c'tor试图访问一个不能在常量表达式中使用的对象作为其评估的一部分(通过所述参考)。所以确实,编译器会抱怨。
| 归档时间: |
|
| 查看次数: |
286 次 |
| 最近记录: |