在 constexpr 函数中改变一个 int

Mutating an int inside a constexpr function

为什么我可以这样做:

constexpr auto i_can() {
   int a = 8;
   a = 9;
   //...
}

但是我不能这样做:

constexpr auto i_cannot() {
    std::array<int, 10> arr{};
    //I cannot
    arr[5] = 9;
}

我的问题是:

  1. 如果我可以改变一个 int,为什么我不能改变数组内部的一个 int
  2. 这是语言限制 (C++14) 还是标准库规范问题? reference std::array<T, N>::operator[](size_t) 当前不是 constexpr

这是标准库的限制,因为您可以修改constexpr:

中的普通 C 数组
#include <iostream>

constexpr auto demo()
{
   int arr[10] = {};
   arr[5] = 9;
   return arr[5];
}

int main()
{
    static_assert(demo() == 9, "");
    std::cout << demo() << std::endl;
    return 0;
}   

DEMO

输出

9

如果您将 constexpr 添加到 array 实现的 operator[],您也可以在 constexpr.

中使用此运算符

DEMO

C++14 引入了 constexpr 函数内对象的修改。但是,在修改例如通过赋值的标量很好,通过成员函数修改 class 对象仍然需要该成员函数为 constexpr。不幸的是,正如您提到的,当前的 std::array 规范并未将非 const operator[] 声明为 constexpr.
因此,§7.1.5/5 使您的定义格式错误:

For a non-template, non-defaulted constexpr function […], if no argument values exist such that an invocation of the function […] could be an evaluated subexpression of a core constant expression (5.20), […], the program is ill-formed; no diagnostic required.

如果您想要完整的 constexpr-ness,您可以暂时使用更现代的实现。例如。 Constainer::Array.