gpt4 book ai didi

c++ - 下标时是否必须使用 constexpr 数组?

转载 作者:太空宇宙 更新时间:2023-11-04 13:35:48 24 4
gpt4 key购买 nike

给定以下代码:

struct A { static constexpr int a[3] = {1,2,3}; };

int main () {
int a = A::a[0];
int b [A::a[1]];
}

A::a 一定是 odr-usedint a = A::a[0]?


注意:这个问题代表了 a debate in the Lounge 的不那么火爆/不合逻辑/没完没了的版本。 .

最佳答案

首次使用A::a:

int a = A::a[0];

初始化器是一个常量表达式,但这并不能阻止A::a 在这里被odr-used。事实上,A::a 被此表达式odr-used

从表达式 A::a[0] 开始,让我们遍历 [basic.def.odr](3.2)/3(对于 future 的读者,我我正在使用 N3936 中的措辞):

A variable x [in our case, A::a] whose name appears as a potentially-evaluated expression ex [in our case, the id-expression A::a] is odr-used unless

  • applying the lvalue-to-rvalue conversion to x yields a constant expression [it does] that does not invoke any non-trivial functions [it does not] and,

  • if x is an object [it is],

    • ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion is applied to e, or e is a discarded-value expression.

那么:e 有哪些可能的值?表达式的一组潜在结果是表达式的一组子表达式(您可以通过阅读[basic.def.odr](3.2)/2 来检查这一点), 所以我们只需要考虑 ex 是子表达式的表达式。它们是:

A::a
A::a[0]

其中,左值到右值的转换不会立即应用于A::a,因此我们只考虑A::a[0 ]。根据 [basic.def.odr](3.2)/2A::a[0] 的潜在结果集为空,因此 A: :a 被此表达式odr-used

现在,您可能会争辩说我们首先将 A::a[0] 重写为 *(A::a + 0)。但这并没有改变:e 的可能值是

A::a
A::a + 0
(A::a + 0)
*(A::a + 0)

其中,只有第四个应用了左值到右值的转换,[basic.def.odr](3.2)/2 再次表示潜在结果集*(A::a + 0) 为空。特别要注意,数组到指针的衰减不是左值到右值的转换 ([conv.lval](4.1)),即使它转换了一个数组左值到指针右值 -- 这是数组到指针的转换 ([conv.array](4.2))。

第二次使用A::a:

int b  [A::a[1]];

按照标准,这与第一种情况没有区别。同样,A::a[1] 是一个常量表达式,因此这是一个有效的数组绑定(bind),但是仍然允许编译器在运行时发出代码来计算这个值,并且数组绑定(bind)仍然odr-uses A::a.

请特别注意,常量表达式(默认情况下)是潜在求值表达式。根据 [basic.def.odr](3.2)/2:

An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) or a subexpression thereof.

[expr](5)/8 只是将我们重定向到其他子条款:

In some contexts, unevaluated operands appear (5.2.8, 5.3.3, 5.3.7, 7.1.6.2). An unevaluated operand is not evaluated.

这些子句分别说明了一些 typeid 表达式的操作数、sizeof 的操作数、noexcept 的操作数,以及decltype 的操作数是未计算的操作数。没有其他类型的未计算的操作数。

关于c++ - 下标时是否必须使用 constexpr 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29640845/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com