Доступ к элементу массива std, переданному как нетипичный параметр шаблона, дает постоянное значение времени компиляции в msvc - PullRequest
1 голос
/ 31 марта 2020

Я пытаюсь передать static constexpr std::array в качестве нетипового параметра шаблона. Однако доступ к элементу массива дает постоянное значение времени компиляции в компиляторе msv c.

MSV C (16.4.5, 16.5) не в состоянии скомпилировать образец, но clang (9, 10) и g cc (9.1, 9.2, 9.3) скомпилировать штраф.

Каково правильное поведение в соответствии с текущими стандартами (> = c ++ 20)? Это ошибка компилятора MSV C?

Вот пример 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";
    });
}

1 Ответ

1 голос
/ 31 марта 2020

Я бы сказал, что это ошибка.

Единственная функция C ++ 20, которую вы используете, - это синтаксис шаблона для лямбд, который согласно документации Microsoft уже должен поддерживаться, поскольку 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 она должна скомпилироваться, потому что вам разрешено передавать ссылку на объект с stati c длительностью хранения в качестве аргумента шаблона и его использование в качестве arr[Index] также является константным выражением, так как ссылка была инициализирована с помощью константного выражения, а указанный объект также является константой initialized.

Тем не менее MSV C по-прежнему выдает то же сообщение об ошибке, будь то в режиме c ++ 2a или c ++ 17. И G CC, и Clang компилируют это в режиме C ++ 17.

...