Проблемы с оператором подскрипта и расширением пакета параметров

Вопрос или проблема

При синтаксической проверке доступа по подписке с помощью расширения пакета параметров я ожидал, что следующий код будет работать без ошибок. Однако MSVC отклоняет как синтаксис ограничения в секции requires, так и последнюю ассерцию.

template<typename T, typename... Ts>
concept c = requires(T t, Ts... ts) {
    { t[ts...] } noexcept;             // clang ok, gcc ok, msvc нет
};

static_assert(not c<int[]>);           // все ок
static_assert(not c<int[], int, int>); // все ок
static_assert(c<int[], int>);          // clang ok, gcc ok, msvc нет

Является ли это просто багом компилятора MSVC? Какое правило в стандарте C++23 определяет этот код как законный?

Демо


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

<source>(3): ошибка C2760: синтаксическая ошибка: 'noexcept' здесь была неожиданной; ожидалось ';'
<source>(3): ошибка C2760: синтаксическая ошибка: ']' здесь была неожиданной; ожидалось '}'
<source>(8): ошибка C2607: статическая проверка не удалась
<source>(8): примечание: концепция 'c<int[],int>' оценена как ложная

Ответ или решение

Ваш вопрос касается использования оператора подстановки и расширения параметрических пакетов в C++23, в частности в контексте концептов. Давайте разберемся с проблемой, которую вы описываете.

Проблема

Вы пытаетесь использовать оператор подстановки в контексте концепта с использованием параметрических пакетов. Ваш код имеет две основные части:

  1. Определение концепта c, который проверяет, можно ли выполнить оператор подстановки t[ts...] с типом T и членами из пакета Ts.
  2. Набор статических утверждений для проверки, действительно ли концепт c выполняется для различных комбинаций типов.

Вы отметили, что MSVC не проходит компиляцию из-за различных синтаксических ошибок, в то время как Clang и GCC обрабатывают этот код корректно.

Стандарты C++

Процитируем некоторые специальные моменты из стандарта C++23:

  1. Правила для requires и концептов — согласно C++20 (и C++23), синтаксис использования requires в концептах позволяет проверять выражения на корректность выполнения. Синтаксис { t[ts...] } noexcept; должен считаться допустимым, так как он используется для проверки на корректность выполнения, включая определение, выбросит ли оно исключение или нет.

  2. Служебные элементы синтаксиса и семантики — вызов operator[] с использованием параметрического пакета ts... должен работать, если T поддерживает такую операцию. Ваша конструкция предполагает, что к t можно применить оператор подстановки с несколькими индексами, что в принципе возможно для массивов и контейнеров.

Ошибки компилятора MSVC

Судя по сообщениям об ошибках, ошибка происходит из-за того, что MSVC неправильно интерпретирует синтаксис в строке noexcept;. В C++23 допускается использование noexcept в данном контексте, и это должно работать. Ошибка expected ';' указывает на то, что компилятор ищет завершение выражения, в то время как он не может правильно проанализировать выражение.

Почему это может быть ошибкой компилятора

Таким образом, возникает вопрос, является ли проблема с MSVC ошибкой компилятора. Вероятно, что реализация в MSVC не полностью соответствует стандарту C++23 в случае работы с концептами и выражениями, использующими суммирующие пакеты. Также возможно, что в конкретной версии компилятора, которую вы используете, не реализованы все новшества стандарта.

Выводы

  1. Ваш код выглядит корректно с точки зрения стандарта C++23, и его ошибки, возникающие в MSVC, можно считать потенциальной проблемой компилятора.

  2. Рекомендуется проверить текущую версию компилятора MSVC и его совместимость со стандартом C++23. Возможно, стоит рассмотреть обновление до последней версии, где данные проблемы могут быть исправлены.

  3. Если проблема сохраняется, вы можете рассмотреть возможность подачи отчета о баге в Microsoft, чтобы разработчики могли исправить эту несоответствие в будущих обновлениях компилятора.

Надеюсь, эта информация поможет вам разобраться с вашей проблемой.

Оцените материал
Добавить комментарий

Капча загружается...