Подтвердить что ты не робот

Почему объявления разложения не могут быть constexpr?

Рассмотрим следующий фрагмент, чтобы проверить предстоящие объявления декомпозиции функций С++ 17 (ранее известные как структурированные привязки)

#include <cassert>
#include <utility>

constexpr auto divmod(int n, int d)
{
    return std::make_pair(n / d, n % d); // in g++7, also just std::pair{n/d, n%d}
}

int main()
{
    constexpr auto [q, r] = divmod(10, 3);
    static_assert(q == 3 && r ==1);
}

Это не работает как g++ 7-SVN, так и clang-4.0-SVN с сообщением:

Объявление декомпозиции не может быть объявлено "constexpr"

Отбрасывание определения constexpr и переход на обычный assert() работает на обоих компиляторах.

Ни одна из работ РГ21 по этой функции не упоминает ключевое слово constexpr, ни в положительном, ни в отрицательном.

Вопрос: почему объявления с декомпозицией не могут быть constexpr? (кроме "потому что стандарт говорит так" ).

4b9b3361

Ответ 1

Вопрос: почему объявления разложения не могут быть constexpr? (кроме "потому что стандарт говорит так" ).

Нет другой причины. Стандарт говорит в [dcl.dcl] p8:

Обозначение-spec-seq должно содержать только спецификатор типа auto (7.1.7.4) и cv-квалификаторы.

Это означает, что он не может быть объявлен с помощью constexpr.

Это было предметом комментариев Национального органа на компакт-диске С++ 17, см. US-95 в P0488R0:

Комментарий: нет очевидной причины, по которой разложение объявления не могут быть объявлены как статические, thread_local или constexpr.
Предлагаемое изменение: Разрешить constexpr, static и thread_local для разрешенный набор спецификаторов decl.

Комментарии GB 16 и GB 17 также связаны.

Эти комментарии были отклонены для С++ 17 после рассмотрения рабочей группой Evolution на встрече в ноябре 2016 года. Было непонятно, что некоторые классы хранения означали бы в объявлении структурированного связывания, и точно, как изменить спецификацию, чтобы позволить constexpr (просто разрешить ее в грамматике не сказать, что это означает). Была запрошена бумага, исследующая пространство для дизайна. Должно быть возможно изменить это в будущем, не нарушая никакого кода, но не было времени сделать это для С++ 17.