本文介绍了const和constexpr数组之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 为什么与数组一起使用时 const 和 constexpr 有区别? int const xs [] {1,2,3}; constexpr int ys [] {1,2,3}; int as [xs [0]]; //错误。 int bs [ys [0]]; //罚款。 我会期望 xs [0] 和 ys [0] 是常量表达式,但只有后者被视为这样。解决方案更长的评论作为社区wiki。 表达式 xs [0 ] 在[expr.sub] / 1中定义为 *((xs)+(0))。 因此,数组到指针的转换[ conv.array]:注意,它可以对左值操作,结果是 prvalue , 0 作为整数文字也是prvalue。添加在[expr.add] / 5中定义。因为两者都是 ,所以不需要进行左值到右值的转换。 int arr [3 ]。 constexpr int * p = arr; //允许并编译 关键的步骤现在似乎是间接 * [expr.unary.op] / 1 因此, xs [0] 的结果是一个左值, xs 数组的第一个元素,类型为 int const 。 注意[expr.prim.general] / 6 现在看看[expr.const] / 2中不允许某些表达式和转换出现在常量表达式中的项目符号,唯一可以应用的项目符号(AFAIK)是左值到右值转换:但只有真正的左值到右值转换在 xs [0] 的评估中出现的(4.1)(不是4.2,它是数组到指针)是从引用第一个元素的结果左值的转换。 对于OP中的示例: int const xs [] {1,2,3}; int as [xs [0]]; //错误。 此元素 xs [0] p>顺便提及,添加了[expr.const] / 2的引用段落中添加的注释以澄清这是合法的: constexpr char c =hello[0] 请注意,字符串文字也是一个左值。 如果有人(可以更改为)解释为什么不允许 xs [0] 出现在常量表达式中。 Why is there a difference between const and constexpr when used with arrays?int const xs[]{1, 2, 3};constexpr int ys[]{1, 2, 3};int as[xs[0]]; // error.int bs[ys[0]]; // fine.I would expect both xs[0] and ys[0] to be constant expressions but only the latter is treated as such. 解决方案 A longer comment as community wiki.The expression xs[0] is defined in [expr.sub]/1 as *((xs)+(0)). (See below for the parantheses.)Therefore, the array-to-pointer conversion [conv.array] is applied:Note it can operate on an lvalue and the result is a prvalue, 0 as an integer literal is a prvalue as well. The addition is defined in [expr.add]/5. As both are prvalues, no lvalue-to-rvalue conversion is required.int arr[3];constexpr int* p = arr; // allowed and compilesThe crucial step now seems to be the indirection * [expr.unary.op]/1So, the result of xs[0] is an lvalue referring to the first element of the xs array, and is of type int const.N.B. [expr.prim.general]/6If we now look at the bullets in [expr.const]/2 which disallow certain expressions and conversions to appear in constant expressions, the only bullet that could apply (AFAIK) is the lvalue-to-rvalue conversion:But the only true lvalue-to-rvalue conversion as per (4.1) (not 4.2, which is array-to-pointer) that appears in the evaluation of xs[0] is the conversion from the resulting lvalue referring to the first element.For the example in the OP:int const xs[]{1, 2, 3};int as[xs[0]]; // error.This element xs[0] has non-volatile const integral type, its initialization precedes the constant expression where it occurs, and it has been initialized with a constant expression.By the way, the added "Note" in the quoted passage of [expr.const]/2 has been added to clarify that this is legal:constexpr char c = "hello"[0];Note that a string literal is an lvalue as well.It would be great if someone (could change this to) explain why xs[0] is not allowed to appear in a constant expression. 这篇关于const和constexpr数组之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 08-22 17:34