Constexpr If (False) ブロックでの static_Assert 動作の失敗
C 17 での constexpr if の導入により、static_asserts の動作に関する懸念が生じました。これらの選択されていないブランチ内で
C 標準によれば、constexpr if ステートメントがテンプレート化されたエンティティに出現する場合、選択されなかったブランチ内の破棄されたステートメントはインスタンス化されません。このルールは、テンプレートのインスタンス化中に非依存の false 条件を指定して static_asserts を実行することを禁止し、プログラムの形式が不正であると事実上みなします。
この動作は、有効な特殊化が生成できない場合という、すべてのテンプレートに適用されるより一般的なルールに由来しています。 constexpr にサブステートメントを含むテンプレートの場合、それが false と評価された場合、テンプレートが正しいかどうかに関係なく、プログラムは不正形式とみなされます。
たとえば、次のコードは不正な形式ですが、Clang の最新バージョンを使用すると警告なしでコンパイルされます。
template< typename T> constexpr void other_library_foo(){ static_assert(std::is_same<T,int>::value); } template<class T> void g() { if constexpr (false) other_library_foo<T>(); }
この動作は、static_asserts への間接的な呼び出しにまで拡張されます。 constexpr (テンプレート) 関数に、非依存の false 条件を持つ static_assert が含まれている場合、別のテンプレート内であっても、constexpr if ステートメントの選択されていない分岐内でこの関数を呼び出すことはできません。
影響と注意事項
constexpr if (false) ブロック内の static_asserts に対するこの制限は、 SFINAE の代替としての constexpr の安全性と有用性。開発者は、そのようなステートメントの取得されなかったブランチ内で間接的に呼び出される可能性のある関数またはライブラリで static_asserts が使用される可能性があることに注意する必要があります。
そのため、次のようなコードで static_asserts を使用することは避けることをお勧めします。 constexpr if (false) ブロックの一部として実行されます。これにより、プログラムの整形式が確保され、潜在的なコンパイラの警告やエラーが回避されます。
以上がC 17 の `constexpr if (false)` ブロックで静的アサーションが失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。