Цикл for в constexpr функция не компилируется с MSVC 19.23 - PullRequest
1 голос
/ 13 октября 2019

Следующий код компилируется в Clang и GCC, но не работает в MSVC.

template <typename... FieldsSequence>
struct S {
    static constexpr bool checkIdUniqueness()
    {
        using IdType = int;
        constexpr IdType fieldIds[sizeof...(FieldsSequence)]{ 0 };
        for (size_t i = 0; i < std::size(fieldIds) - 1; ++i)
        {
            if (fieldIds[i] > fieldIds[i + 1])
            {
                constexpr auto tmp = fieldIds[i];
                fieldIds[i] = fieldIds[i + 1];
                fieldIds[i + 1] = tmp;
            }
        }

        return true;
    }
};

Сообщение об ошибке:

expression did not evaluate to a constant
note: failure was caused by a read of a variable outside its lifetime
note: see usage of 'i'

Есть ли способ заставить это работать со всемитри компилятора? В конечном счете, мне нужно отсортировать массив, чтобы во время компиляции утверждать, что все значения уникальны.

https://godbolt.org/z/9XbP6-

1 Ответ

4 голосов
/ 13 октября 2019

Вы злоупотребили constexpr декларациями. Во-первых, если fieldIds объявлено constexpr, то это также const, и вы не можете изменить его. Что касается tmp, поскольку он объявлен constexpr, инициализатор должен быть константным выражением, но на самом деле это не может быть одно.

Правильный подход состоит в том, чтобы удалить constexpr из этих объявлений:

template <typename... FieldsSequence>
struct S {
    static constexpr bool checkIdUniqueness()
    {
        using IdType = int;
        IdType fieldIds[sizeof...(FieldsSequence)]{ 0 };
        for (size_t i = 0; i < std::size(fieldIds) - 1; ++i)
        {
            if (fieldIds[i] > fieldIds[i + 1])
            {
                auto tmp = fieldIds[i];
                fieldIds[i] = fieldIds[i + 1];
                fieldIds[i + 1] = tmp;
            }
        }

        return true;
    }
};

Функция в целом все еще может быть оценена в константном выражении , но теперь нет дополнительных требований к этим переменным, которые могут помешать их объявлению или использованию.

...