无法让 std::array 的 data() 方法用作 constexpr,我在做傻事吗?

Can't get std::array's data() method to work as a constexpr, am I doing something silly?

提问人:Danny 提问时间:11/3/2023 更新时间:11/3/2023 访问量:90

问:

因此,根据 CPP 参考,我应该能够用作 constexpr。我的最小例子是这样的:data()

#include <array>
#include <iostream>


int main(int argc,char** argv){
    using Container_t = std::array<double, 10>;

    constexpr Container_t arr{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    constexpr const double* data = arr.data();

    return arr[0];
}

这是这段代码产生的编译错误。我在所有主要编译器上都看到了类似的错误,所以我一定遗漏了一些关于规范允许的内容,但这似乎是一个简单的案例。谢谢!

C++ 数组标准

评论

0赞 PaulMcKenzie 11/3/2023
您没有启用 C++17 编译
0赞 Danny 11/3/2023
@PaulMcKenzie嗯,我不确定为什么会编译。我肯定在我的本地机器上使用 C++20 标志,但它没有,也没有使用带有 C++ 标志的 Clang 进行编译。godbolt.org/z/6exGoz83a
0赞 Danny 11/3/2023
@PaulMcKenzie 若要跟进,如果切换到更新版本的 MSVC,则会失败
0赞 Jesper Juhl 11/3/2023
旁注:暗示 .所以是多余的。constexprconstconstexpr const ...
1赞 JaMiT 11/3/2023
@JesperJuhl “所以 constexpr const ...是多余的“——并非总是如此。它在声明中是多余的,它声明 both 和 。但是,它在 中不是多余的,它声明了 is 和 is 。constexpr const double datadataconstexprconstconstexpr const double* datadataconstexpr*dataconst

答:

3赞 Artyer 11/3/2023 #1

指针必须指向具有静态存储持续时间的内容。constexpr

your 没有固定地址,因为它是局部变量,所以不能是常量表达式。arrarr.data()

它可以用作常量表达式的一部分

constexpr Container_t arr{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
static_assert(arr.data()[2] == 3.0);
static_assert(arr.data() + 3 == &arr[3]);

如果希望它是一个常量表达式,请使具有静态存储持续时间:arr

static constexpr Container_t arr{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
constexpr const double* data = arr.data();

评论

0赞 Danny 11/3/2023
谢谢@artyer,这是有道理的,并回答了我最初的问题。如果我不想要对象的静态持续时间,您是否建议任何解决方法?
0赞 Artyer 11/3/2023
@Danny 本地数组通常就像从未命名的静态存储持续时间对象复制一样,因此仅添加以摆脱中间人通常没有缺点。示例:godbolt.org/z/jx1v7Wz1P .如果您在 C++23 之前的 constexpr 函数中(不能使用 ),请将局部变量设置为全局变量。您也可以改为在数据中使用索引(而不是 having 和 , have 和 use )。constexprstaticstatic constexprconstexpr const double* data = arr.data() + n*dataconstexpr std::size_t index = n;data[n]
0赞 Danny 11/4/2023
为此,我最终选择了后一种方法,并制作了一些原型,可以在没有静态存储持续时间的情况下获得我想要的东西。