static_assert

コンパイル時にソフトウェアのアサーションをテストします。 指定された定数式が false の場合、コンパイラには、指定されたメッセージが表示され、1 が指定されると、コンパイルはエラー C2338 で失敗します。それ以外の場合、宣言は無効です。

構文

static_assert( constant-expression, string-literal );

static_assert( constant-expression ); // C++17 (Visual Studio 2017 and later)

パラメーター

constant-expression
ブール型に変換できる整数定数式。 評価された式がゼロ (false) の場合、string-literal パラメーターが表示され、コンパイルはエラーで失敗します。 条件がゼロ以外 (true) の場合、static_assert 宣言は無効です。

string-literal
定数式パラメーターが 0 の場合に表示されるメッセージ。 メッセージは、コンパイラの基本文字セットの文字列です。つまり、マルチバイトまたはワイド文字ではありません。

解説

static_assert 宣言の constant-expression パラメーターは、ソフトウェアのアサーションを表します。 ソフトウェアのアサーションは、プログラムの特定位置にある true となるはずの条件を指定します。 条件が true の場合、static_assert 宣言は無効です。 条件が false の場合、アサーションは失敗し、コンパイラは string-literal パラメーターのメッセージを表示し、コンパイルはエラーで失敗します。 Visual Studio 2017 以降では、文字列リテラル パラメーターは省略可能です。

static_assert 宣言は、コンパイル時にソフトウェアのアサーションをテストします。 これに対し、実行時は、assert マクロ、および_assert 関数と _wassert 関数によってソフトウェアのアサーションがテストされ、スペースまたは時刻でのランタイム コストが発生します。 static_assert の宣言は、テンプレート引数を constant-expression パラメーターに含めることができるため、テンプレートをデバッグする場合に特に便利です。

コンパイラは、宣言を検出すると、static_assert 宣言をチェックして構文エラーを探します。 テンプレート パラメーターに依存しない場合、コンパイラは constant-expression パラメーターを直ちに評価します。 それ以外の場合、テンプレートがインスタンス化されるときに、コンパイラは constant-expression パラメーターを評価します。 その結果、コンパイラは、宣言を検出したときに一度、テンプレートがインスタンス化されたときに再度、診断メッセージを発行することがあります。

static_assert キーワードは、名前空間、クラス、またはブロック スコープで使用できます。 static_assert キーワードは、名前空間スコープで使用できるため、プログラムに新しい名前を組み込むことはありませんが、技術的には宣言です。

名前空間スコープを持つ static_assert の説明

次の例では、static_assert 宣言は名前空間スコープを持ちます。 コンパイラは void * 型のサイズがわかっているので、式は直ちに評価されます。

例: 名前空間スコープを使用する static_assert

static_assert(sizeof(void *) == 4, "64-bit code generation is not supported.");

クラス スコープを持つ static_assert の説明

次の例では、static_assert 宣言はクラス スコープを持ちます。 static_assert は、テンプレート パラメーターが plain old data (POD) 型であることを検証します。 コンパイラは static_assert が宣言されている場合はそれをチェックしますが、basic_string クラス テンプレートが main() でインスタンス化されるまで constant-expression パラメーターを評価しません。

例: クラス スコープを持つ static_assert

#include <type_traits>
#include <iosfwd>
namespace std {
template <class CharT, class Traits = std::char_traits<CharT> >
class basic_string {
    static_assert(std::is_pod<CharT>::value,
                  "Template argument CharT must be a POD type in class template basic_string");
    // ...
    };
}

struct NonPOD {
    NonPOD(const NonPOD &) {}
    virtual ~NonPOD() {}
};

int main()
{
    std::basic_string<char> bs;
}

ブロック スコープを持つ static_assert の説明

次の例では、static_assert 宣言はブロック スコープを持ちます。 static_assert は、VMPage 構造体のサイズがシステムの仮想メモリ pagesize と等しいことを検証します。

例: ブロック スコープでの static_assert

#include <sys/param.h> // defines PAGESIZE
class VMMClient {
public:
    struct VMPage { // ...
           };
    int check_pagesize() {
    static_assert(sizeof(VMPage) == PAGESIZE,
        "Struct VMPage must be the same size as a system virtual memory page.");
    // ...
    }
// ...
};

関連項目

アサーションとユーザー指定のメッセージ (C++)
#error ディレクティブ (C/C++)
assert マクロ、_assert、_wassert
テンプレート
ASCII 文字セット
宣言と定義