static_assert 宣言 (C++11以降)
From cppreference.com
コンパイル時アサーションチェックを実行する。
目次 |
[編集] 構文
static_assert( bool-constexpr , unevaluated-string ) |
(1) | ||||||||
static_assert( bool-constexpr ) |
(2) | (C++17以降) | |||||||
static_assert( bool-constexpr , constant-expression ) |
(3) | (C++26以降) | |||||||
静的アサーションを宣言する。アサーションが失敗した場合、プログラムは不正な形式となり、診断エラーメッセージが生成される可能性がある。
1) 固定のエラーメッセージを持つ静的アサーション。
2) エラーメッセージを持たない静的アサーション。
3) ユーザー生成のエラーメッセージを持つ静的アサーション。
この構文は、構文 (1) が一致しない場合にのみ一致する。
[編集] 説明
| bool-constexpr | - |
| ||||
| unevaluated-string | - | エラーメッセージとして表示される評価されない文字列リテラル | ||||
| 定数式 | - | 以下のすべての条件を満たす定数式 msg
|
static_assert 宣言は、名前空間スコープとブロックスコープ(ブロック宣言として)、およびクラス本体内(メンバー宣言として)に現れることができる。
bool-constexpr が適切に形成され、true に評価される場合、またはテンプレート定義のコンテキストで評価され、テンプレートがインスタンス化されていない場合、この宣言は効果がない。そうでない場合、コンパイル時エラーが発行され、ユーザー提供のメッセージがあれば、診断メッセージに含まれる。
ユーザー提供メッセージのテキストは、次のように決定される
- メッセージが unevaluated-string の構文要件に一致する場合、メッセージのテキストは unevaluated-string のテキストである。
|
(C++26以降) |
[編集] 備考
標準では、コンパイラがエラーメッセージの文字通りのテキストを出力することを要求していないが、コンパイラは一般的に可能な限りそうしている。
|
エラーメッセージは文字列リテラルである必要があるため、動的な情報や、文字列リテラル自体ではない定数式を含めることはできない。特に、テンプレート型引数の名前を含めることはできない。 |
(C++26まで) |
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_static_assert |
200410L |
(C++11) | static_assert (構文 (1)) |
201411L |
(C++17) | 単一引数 static_assert (構文 (2)) | |
202306L |
(C++26) | ユーザー生成エラーメッセージ (構文 (3)) |
[編集] キーワード
[編集] 例
このコードを実行
#include <format> #include <type_traits> static_assert(03301 == 1729); // since C++17 the message string is optional template<class T> void swap(T& a, T& b) noexcept { static_assert(std::is_copy_constructible_v<T>, "Swap requires copying"); static_assert(std::is_nothrow_copy_constructible_v<T> && std::is_nothrow_copy_assignable_v<T>, "Swap requires nothrow copy/assign"); auto c = b; b = a; a = c; } template<class T> struct data_structure { static_assert(std::is_default_constructible_v<T>, "Data structure requires default-constructible elements"); }; template<class> constexpr bool dependent_false = false; // workaround before CWG2518/P2593R1 template<class T> struct bad_type { static_assert(dependent_false<T>, "error on instantiation, workaround"); static_assert(false, "error on instantiation"); // OK because of CWG2518/P2593R1 }; struct no_copy { no_copy(const no_copy&) = delete; no_copy() = default; }; struct no_default { no_default() = delete; }; #if __cpp_static_assert >= 202306L // Not real C++ yet (std::format should be constexpr to work): static_assert(sizeof(int) == 4, std::format("Expected 4, got {}", sizeof(int))); #endif int main() { int a, b; swap(a, b); no_copy nc_a, nc_b; swap(nc_a, nc_b); // 1 [[maybe_unused]] data_structure<int> ds_ok; [[maybe_unused]] data_structure<no_default> ds_error; // 2 }
実行結果の例
1: error: static assertion failed: Swap requires copying 2: error: static assertion failed: Data structure requires default-constructible elements 3: error: static assertion failed: Expected 4, got 2
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 2039 | C++11 | 変換前の式のみが定数である必要がある | 変換もそうである必要がある 定数式で有効 |
| CWG 2518 (P2593R1) |
C++11 | 未インスタンス化 static_assert(false, ""); は不正な形式だった | 適切な形式になった |
[編集] 参照
- C++23標準 (ISO/IEC 14882:2024)
- 9.1 Preamble [dcl.pre] (p: 10)
- C++20 standard (ISO/IEC 14882:2020)
- 9.1 Preamble [dcl.pre] (p: 6)
- C++17 standard (ISO/IEC 14882:2017)
- 10 Declarations [dcl.dcl] (p: 6)
- C++14 standard (ISO/IEC 14882:2014)
- 7 Declarations [dcl.dcl] (p: 4)
- C++11 standard (ISO/IEC 14882:2011)
- 7 Declarations [dcl.dcl] (p: 4)
[編集] 関連項目
| 指定されたエラーメッセージを表示し、プログラムを不正な形式にする (プリプロセッサディレクティブ) | |
| ユーザー指定の条件が true でない場合にプログラムを異常終了させる。リリースビルドでは無効化されることがある。 (関数マクロ) | |
contract_assert文 (C++26) |
実行中に内部条件を検証する |
| (C++11) |
条件に応じて関数のオーバーロードやテンプレートの特殊化をオーバーロード解決から除外する (クラステンプレート) |
| 型特性 (C++11) | 型のプロパティを問い合わせるコンパイル時テンプレートベースインターフェースを定義する |
| C documentation for Static assertion
| |