在constexpr函数内变换int

Ger*_*ago 23 c++ constexpr c++14

我为什么这样做:

constexpr auto i_can() {
   int a = 8;
   a = 9;
   //...
}
Run Code Online (Sandbox Code Playgroud)

但我不能这样做:

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

我的问题是:

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

Col*_*mbo 17

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

对于非模板,非默认constexpr函数[...],如果不存在参数值,则函数[...]的调用可以是核心常量表达式(5.20)的评估子表达式,[...],程序为形成不良; 无需诊断.

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

  • @GermánDiago好,使用[`Constainer :: Bitset`(https://github.com/Arcoth/Constainer/blob/master/Bitset.hxx):-P (2认同)
  • 只是一个观察,"constainer"实际上是Columbo所指的库的名称,而不是拼写错误. (2认同)

m.s*_*.s. 16

它是标准库的限制,因为您可以在以下位置修改普通C数组constexpr:

#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;
}   
Run Code Online (Sandbox Code Playgroud)

DEMO

产量

9
Run Code Online (Sandbox Code Playgroud)

如果添加constexproperator[]的实现的array,你也可以使用该运营商内部 constexpr.

DEMO

  • 这是猜测还是答案? (2认同)