2017-01-12 4 views
34

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

#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); 
} 

Это терпит неудачу на обоих г ++ 7-SVN и лязг-4.0-SVN с сообщением :

декларация разложения не может быть объявлен «constexpr»

сбросив constexpr определение и меняющийся на регулярной assert() работает как со mpilers.

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

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

ответ

35

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

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

Децл-спецификатор-сл должен содержать только тип спецификаторauto (7.1.7.4) и CV-отборочные.

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

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

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

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

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

+5

ОК, поэтому поддержка 'constexpr' может быть добавлена ​​в предстоящую встречу Kona? – TemplateRex

+1

@TemplateRex: комментарии Национального органа являются официальными ответами на ИСО, и до официального релиза им необходимо будет ответить. Но предлагаемое изменение вполне может быть отклонено, например. если есть серьезные сомнения в непредвиденных побочных эффектах этих изменений. Тем не менее, если есть неочевидная причина, эта причина, вероятно, заслуживает внимания. – MSalters

+2

@MSalters спасибо. Я был бы разочарован, если бы это не было принято. Я был бы еще один момент, чтобы помнить, что нельзя использовать при написании функций constexpr. – TemplateRex