gpt4 book ai didi

c++ - 访问作为非类型模板参数传递的std数组元素会在msvc上给出非编译时常量值

转载 作者:行者123 更新时间:2023-12-02 10:19:10 27 4
gpt4 key购买 nike

我正在尝试将static constexpr std::array作为非类型模板参数传递。但是,访问数组元素会在msvc编译器上提供非编译时常量值。

MSVC(16.4.5,16.5)无法编译示例,但是clang(9,10)和gcc(9.1,9.2,9.3)可以很好地编译。

根据当前标准(> = c++ 20),正确的行为是什么?这是MSVC编译器错误吗?

这是示例https://godbolt.org/z/7YsnAF

#include <array>
#include <iostream>

template <typename T, size_t N, const std::array<T, N> & arr, typename Fn, size_t Index = 0>
void iterate_static_array(Fn && fn) {
static constexpr T e = arr[Index];
fn.template operator()<e>();
if constexpr (Index + 1 < N) {
iterate_static_array<T, N, arr, Fn, Index + 1>(std::forward<Fn>(fn));
}
}

int main() {
static constexpr std::array<int, 10> values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
iterate_static_array<int, 10, values>([]<int e>() {
std::cout << "compile-time e = " << e << "\n";
});
}

最佳答案

我会说这是一个错误。

您使用的唯一C++ 20功能是lambda的模板语法,根据Microsoft's documentation的规定,自VS 2019 16.2起应已支持该语法。

如果您将其删除并进行测试,例如以下程序:

#include <array>
#include <iostream>

template <typename T, size_t N, const std::array<T, N> & arr, typename Fn, size_t Index = 0>
void iterate_static_array(Fn && fn) {
static constexpr T e = arr[Index];
fn.operator()();
if constexpr (Index + 1 < N) {
iterate_static_array<T, N, arr, Fn, Index + 1>(std::forward<Fn>(fn));
}
}

int main() {
static constexpr std::array<int, 10> values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
iterate_static_array<int, 10, values>([]() {
});
}

那么就没有C++ 20功能了,因为C++ 17应该可以编译,因为您可以将静态存储持续时间的引用作为模板参数传递给对象,并且它作为 arr[Index]的用法也是一个常量表达式,例如使用常量表达式对引用进行初始化,并且对引用对象也进行常量初始化。

无论是在c++ 2a还是c++ 17模式下,MSVC仍会给出相同的错误消息。 GCC和Clang都在C++ 17模式下进行编译。

关于c++ - 访问作为非类型模板参数传递的std数组元素会在msvc上给出非编译时常量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60953394/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com