次の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
にできないのはなぜですか? (「標準がそう言っているから」は別として)。
質問:分解宣言をconstexprにできないのはなぜですか? (「標準がそう言っているから」を除いて)。
他に理由はありません。標準は[dcl.dcl] p8で述べています:
decl-specifier-seqにはtype-specifier
auto
(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で変更する時間はありませんでした。