static_assert
声明 (C++11 起)
来自 cppreference.cn
执行编译时断言检查。
目录 |
[编辑] 语法
static_assert( 布尔常量表达式 , 未求值字符串 ) |
(1) | ||||||||
static_assert( 布尔常量表达式 ) |
(2) | (C++17 起) | |||||||
static_assert( 布尔常量表达式 , 常量表达式 ) |
(3) | (C++26 起) | |||||||
声明一个静态断言。如果断言失败,程序格式不正确,并且可能会生成诊断错误消息。
1) 带有固定错误消息的静态断言。
2) 没有错误消息的静态断言。
3) 带有用户生成错误消息的静态断言。
只有当语法 (1) 不匹配时,才能匹配此语法。
[编辑] 解释
布尔常量表达式 | - |
| ||||
未求值字符串 | - | 一个未求值的字符串字面量,它将作为错误消息出现 | ||||
常量表达式 | - | 一个常量表达式 msg 满足以下所有条件
|
一个 static_assert 声明可以出现在命名空间和块作用域(作为块声明)以及类体内(作为成员声明)。
如果 布尔常量表达式 格式正确且求值为 true,或者在模板定义的上下文中求值且模板未实例化,则此声明无效。否则,将发出编译时错误,并且诊断消息中将包含用户提供的消息(如果有)。
用户提供消息的文本确定如下
- 如果消息匹配 未求值字符串 的语法要求,则消息的文本是 未求值字符串 的文本。
|
(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++ 标准。
缺陷报告 | 应用于 | 发布时的行为 | 正确的行为 |
---|---|---|---|
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 文档 用于 静态断言
|