命名空间
变体
操作

static_assert 声明 (自 C++11 起)

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句(循环)
for
范围 for (C++11)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (直至 C++17*)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储期说明符
初始化
 
 

执行编译时断言检查。

内容

[编辑] 语法

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 -

一个语境转换到 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 的文本。
  • 否则,给定以下值
消息的文本由 len代码单元的序列组成,从 ptr 开始,使用普通字面量编码。对于 [0len) 中的每个整数 iptr[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); // 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 序言 [dcl.pre] (p: 10)
  • C++20 标准 (ISO/IEC 14882:2020)
  • 9.1 序言 [dcl.pre] (p: 6)
  • C++17 标准 (ISO/IEC 14882:2017)
  • 10 声明 [dcl.dcl] (p: 6)
  • C++14 标准 (ISO/IEC 14882:2014)
  • 7 声明 [dcl.dcl] (p: 4)
  • C++11 标准 (ISO/IEC 14882:2011)
  • 7 声明 [dcl.dcl] (p: 4)

[编辑] 参见

显示给定的错误消息并使程序成为非良构
(预处理指令)[编辑]
如果用户指定的条件不为 true,则中止程序。可能会在发布版本中禁用。
(函数宏) [编辑]
contract_assert 语句 (C++26) 在执行期间验证内部条件[编辑]
(C++11)
有条件地从重载解析中移除函数重载或模板特化
(类模板) [编辑]
类型特性 (C++11) 定义基于编译时模板的接口以查询类型的属性
C 文档 关于 静态断言