web-dev-qa-db-ja.com

分解宣言を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にできないのはなぜですか? (「標準がそう言っているから」は別として)。

39
TemplateRex

質問:分解宣言をconstexprにできないのはなぜですか? (「標準がそう言っているから」を除いて)。

他に理由はありません。標準は[dcl.dcl] p8で述べています:

decl-specifier-seqにはtype-specifierauto(7.1.7.4)とcv-qualifiersのみが含まれます。

つまり、constexprでは宣言できません。

これは、C++ 17 CDのNational Bodyコメントの件名でした。US-95の P0488R を参照してください。

コメント:分解宣言をstatic、thread_local、またはconstexprとして宣言できない明確な理由はありません。
提案された変更:decl-specifiersの許可されたセットへのconstexpr、static、およびthread_localを許可します。

コメントGB 16とGB 17も関連しています。

これらのコメントは、2016年11月の会議でのEvolutionワーキンググループによるレビューの後、C++ 17で拒否されました。構造化バインディング宣言で一部のストレージクラスが何を意味するか、およびconstexprを許可するように仕様を変更する方法が正確に不明でした(単に文法でそれを許可しても、意味がわかりません)。設計空間を探索する論文が要求されました。コードを壊すことなく、将来的にこれを変更できるはずですが、C++ 17で変更する時間はありませんでした。

38
Jonathan Wakely