Namespaces
Variants

static_assert declaration (since C++11)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

执行编译时断言检查。

目录

语法

static_assert( 布尔常量表达式 , 未求值字符串 ) (1)
static_assert( 布尔常量表达式 ) (2) (C++17 起)
static_assert( 布尔常量表达式 , 常量表达式 ) (3) (C++26 起)

声明一个静态断言。若断言失败,则程序非良构,并可能生成诊断错误信息。

1) 带有固定错误消息的静态断言。
2) 不带错误消息的静态断言。
3) 带有用户自定义错误消息的静态断言。
仅当语法 ( 1 ) 不匹配时才能匹配此语法。

说明

bool-constexpr -

一个 上下文转换为 bool 类型的常量表达式 。不允许内置转换,但允许到 bool 的非 窄化 整型转换

(C++23 前)

一个 上下文转换为 bool 的表达式,且该转换是 常量表达式

(C++23 起)
unevaluated-string - 一个将作为错误信息出现的 未求值字符串字面量
constant-expression - 满足以下所有条件的 常量表达式 msg
  • msg. size ( ) 可隐式转换为 std::size_t
  • msg. data ( ) 可隐式转换为 const char *

static_assert 声明可以出现在命名空间和作用域(作为块声明),也可以出现在类体内(作为成员声明)。

bool-constexpr 格式正确且求值为 true ,或在模板定义上下文中求值且模板未实例化,则此声明无实际作用。否则将产生编译时错误,且诊断信息中会包含用户提供的消息(若有)。

用户提供消息的文本按以下方式确定:

  • 如果消息符合 unevaluated-string 的语法要求,则消息的文本即为该 unevaluated-string 的文本内容。
  • 否则,给定以下值:
消息文本由始于 ptr len 代码单元 序列构成,编码格式为 普通字面量编码 。对于区间 [ 0 , len ) 内的每个整数 i ptr [ i ] 必须是 整型常量表达式
(C++26 起)

注释

标准不要求编译器必须打印 错误信息 的原文,但编译器通常会尽可能这样做。

由于错误信息必须是字符串字面量,它不能包含动态信息,甚至不能包含非字符串字面量本身的 常量表达式 。特别地,它不能包含 模板类型参数 名称

(C++26 前)
功能测试宏 标准 功能特性
__cpp_static_assert 200410L (C++11) static_assert (语法 ( 1 ) )
201411L (C++17) 单参数 static_assert (语法 ( 2 ) )
202306L (C++26) 用户生成的错误消息 (语法 ( 3 ) )

关键词

static_assert

示例

#include <format>
#include <type_traits>
static_assert(03301 == 1729); // 自 C++17 起,消息字符串是可选的
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; // 在 CWG2518/P2593R1 之前的变通方案
template<class T>
struct bad_type
{
    static_assert(dependent_false<T>, "error on instantiation, workaround");
    static_assert(false, "error on instantiation"); // 由于 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
// 还不是真正的 C++(std::format 应为 constexpr 才能工作):
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: 错误:静态断言失败:Swap requires copying
2: 错误:静态断言失败:Data structure requires default-constructible elements
3: 错误:静态断言失败:Expected 4, got 2

缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的C++标准。

缺陷报告 应用于 发布时的行为 正确行为
CWG 2039 C++11 仅要求转换前的表达式为常量 转换本身也必须在常量表达式中有效
CWG 2518
( P2593R1 )
C++11 未实例化的 static_assert ( false , "" ) ; 属于非良构 改为良构

参考文献

  • C++23 标准 (ISO/IEC 14882:2024):
  • 9.1 前导声明 [dcl.pre] (页码: 10)
  • C++20 标准 (ISO/IEC 14882:2020):
  • 9.1 前导声明 [dcl.pre] (页: 6)
  • C++17 标准 (ISO/IEC 14882:2017):
  • 10 声明 [dcl.dcl] (页: 6)
  • C++14 标准 (ISO/IEC 14882:2014):
  • 7 声明 [dcl.dcl] (页: 4)
  • C++11 标准 (ISO/IEC 14882:2011):
  • 7 声明 [dcl.dcl] (页: 4)

参见

显示指定错误信息并使程序格式错误
(预处理指令)
当用户指定条件不为 true 时终止程序。发行版本中可能被禁用
(函数宏)
contract_assert 语句 (C++26) 在运行时验证内部条件
(C++11)
根据条件从重载决议中 移除 函数重载或模板特化
(类模板)
类型特征 (C++11) 定义基于模板的编译时接口以查询类型属性
C 文档 用于 静态断言