在 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;
}
我的问题是:
- 如果我可以改变一个
int
,为什么我不能改变数组内部的一个 int
?
- 这是语言限制 (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;
}
输出
9
如果您将 constexpr
添加到 array
实现的 operator[]
,您也可以在 constexpr
.
中使用此运算符
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
.
为什么我可以这样做:
constexpr auto i_can() {
int a = 8;
a = 9;
//...
}
但是我不能这样做:
constexpr auto i_cannot() {
std::array<int, 10> arr{};
//I cannot
arr[5] = 9;
}
我的问题是:
- 如果我可以改变一个
int
,为什么我不能改变数组内部的一个int
? - 这是语言限制 (C++14) 还是标准库规范问题?
reference std::array<T, N>::operator[](size_t)
当前不是constexpr
。
这是标准库的限制,因为您可以修改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;
}
输出
9
如果您将 constexpr
添加到 array
实现的 operator[]
,您也可以在 constexpr
.
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
.