类型特质和静态断言

发布时间:2024年01月11日

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
当?constant-expression?参数为零时显示的消息。 该消息是编译器的基本字符集中的一个字符串;即,不是多字节或宽字符

注解

static_assert?声明的?constant-expression?参数表示软件断言。 软件断言指定在程序的某个特定点应满足的条件。 如果条件为 true,则?static_assert?声明无效。 如果条件为 false,则断言失败,编译器在?string-literal?参数中显示消息,并且编译失败,出现错误。 在 Visual Studio 2017 及更高版本中,string-literal 参数是可选的。

static_assert?声明在编译时测试软件断言。 相反,assert 宏、_assert 和 _wassert 函数在运行时测试软件断言,并产生运行时空间或时间成本。?static_assert?声明对调试模板尤其有用,因为模板自变量可包含在?constant-expression?中。

当遇到声明时,编译器将检查?static_assert?声明是否存在语法错误。 如果编译器不依赖于模板参数,则编译器会立即计算?constant-expression?参数。 否则,在对模板进行实例化时,编译器将计算?constant-expression?参数。 因此,当遇到声明时,编译器可能一次发布一个诊断消息,而在对模板进行实例化时也是如此。

可以在命名空间、类或块范围中使用?static_assert?关键字。 (由于?static_assert?关键字可以在命名空间范围内使用,因此,即使它不将新名称引到程序中,但从技术上讲,它也是一个声明。)

示例:具有类范围?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?在块范围内

#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.");
    // ...
    }
// ...
};

文章来源:https://blog.csdn.net/hd51cc/article/details/135537523
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。