来自非 constexpr 调用的 constexpr 结果
constexpr result from non-constexpr call
最近令我惊讶的是以下代码也能在 clang、gcc 和 msvc 中编译(至少在它们当前的版本中)。
struct A {
static const int value = 42;
};
constexpr int f(A a) { return a.value; }
void g() {
A a; // Intentionally non-constexpr.
constexpr int kInt = f(a);
}
我的理解是对 f
的调用不是 constexpr,因为参数 i
不是,但看来我错了。这是正确的标准支持代码还是某种编译器扩展?
如评论中所述,常量表达式的规则通常不要求表达式中提到的每个变量,其生命周期开始于表达式评估之外的是 constexpr
。
有 a (long) list 的要求,当不满足时,表达式不能成为常量表达式。只要违反了none条,表达式就是常量表达式。
使用的 variable/object 是 constexpr
的要求正式称为对象 可用于常量表达式(尽管确切的定义包含更详细的要求和例外情况,另请参阅链接的 cppreference 页面)。
查看列表,您可以看到此 属性 仅在某些情况下才需要,即仅适用于 variables/objects,其生命周期开始于表达式之外,并且如果执行虚函数调用它,对其执行 lvalue-to-rvalue 转换,或者它是表达式中命名的引用变量。
这些情况均不适用于此处。没有涉及虚函数,a
不是引用变量。通常,lvalue-to-rvalue 转换会使需求变得重要。每当您尝试使用对象或其子对象之一中存储的值时,就会发生 lvalue-to-rvalue 转换。但是 A
是一个没有任何状态的空 class,因此没有可读的值。在将a
传递给函数时,调用了隐式拷贝构造函数来构造f
的参数,但由于class为空,实际上并没有做任何事情。它不访问 a
.
的任何状态
请注意,如上所述,如果您使用引用,规则会更严格,例如
A a;
A& ar = a;
constexpr int kInt = f(ar);
会失败,因为 ar
命名了一个在常量表达式中不可用的引用变量。这有望很快得到修复,以更加一致。 (参见 https://github.com/cplusplus/papers/issues/973)
最近令我惊讶的是以下代码也能在 clang、gcc 和 msvc 中编译(至少在它们当前的版本中)。
struct A {
static const int value = 42;
};
constexpr int f(A a) { return a.value; }
void g() {
A a; // Intentionally non-constexpr.
constexpr int kInt = f(a);
}
我的理解是对 f
的调用不是 constexpr,因为参数 i
不是,但看来我错了。这是正确的标准支持代码还是某种编译器扩展?
如评论中所述,常量表达式的规则通常不要求表达式中提到的每个变量,其生命周期开始于表达式评估之外的是 constexpr
。
有 a (long) list 的要求,当不满足时,表达式不能成为常量表达式。只要违反了none条,表达式就是常量表达式。
使用的 variable/object 是 constexpr
的要求正式称为对象 可用于常量表达式(尽管确切的定义包含更详细的要求和例外情况,另请参阅链接的 cppreference 页面)。
查看列表,您可以看到此 属性 仅在某些情况下才需要,即仅适用于 variables/objects,其生命周期开始于表达式之外,并且如果执行虚函数调用它,对其执行 lvalue-to-rvalue 转换,或者它是表达式中命名的引用变量。
这些情况均不适用于此处。没有涉及虚函数,a
不是引用变量。通常,lvalue-to-rvalue 转换会使需求变得重要。每当您尝试使用对象或其子对象之一中存储的值时,就会发生 lvalue-to-rvalue 转换。但是 A
是一个没有任何状态的空 class,因此没有可读的值。在将a
传递给函数时,调用了隐式拷贝构造函数来构造f
的参数,但由于class为空,实际上并没有做任何事情。它不访问 a
.
请注意,如上所述,如果您使用引用,规则会更严格,例如
A a;
A& ar = a;
constexpr int kInt = f(ar);
会失败,因为 ar
命名了一个在常量表达式中不可用的引用变量。这有望很快得到修复,以更加一致。 (参见 https://github.com/cplusplus/papers/issues/973)