Почему объявления декомпозиции не могут быть constexpr?

Рассмотрим следующий фрагмент кода для проверки готовящихся объявлений декомпозиции функций C++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() работает на обоих компиляторах.

Ни в одном документе WG21, посвященном этой функции, не упоминается constexpr ключевое слово, ни в положительном, ни в отрицательном.

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

1 ответ

Решение

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

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

Decl-specier-seq должен содержать только спецификатор типа auto (7.1.7.4) и cv-квалификаторы.

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

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

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

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

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

Другие вопросы по тегам