C++11 static_assert关键字

简介: C++11 static_assert关键字

static_assert简介


我们知道,C++现有的标准中就有assert、#error两个方法是用来检查错误的,除此而外还有一些第三方的静态断言实现。


assert是运行期断言,它用来发现运行期间的错误,不能提前到编译期发现错误,也不具有强制性,也谈不上改善编译信息的可读性。


既然是运行期检查,对性能肯定是有影响的,所以经常在发行版本中,assert都会被关掉。


#error可看作是预编译期断言(甚至都算不上断言),仅仅能在预编译时显示一个错误信息,可以配合#ifdef/ifndef参与预编译的条件检查。


由于它无法获得编译信息,当然,也就做不了更进一步分析了。


在stastic_assert提交到C++0x标准之前,为了弥补assert和#error的不足,出现了一些第三方解决方案,可以作编译期的静态检查:


static_assert关键字,用来做编译期间的断言,因此叫做静态断言。


static_assert语法:


static_assert(常量表达式,提示字符串)。


参数描述:


  • 如果第一个参数常量表达式的值为false,会产生一条编译错误,错误位置就是该static_assert语句所在行


  • 第二个参数就是错误提示字符串。


static_assert作用:


使用static_assert,我们可以在编译期间发现更多的错误,用编译器来强制保证一些契约,并帮助我们改善编译信息的可读性,尤其是用于模板的时候。


static_assert可以用在全局作用域中,命名空间中,类作用域中,函数作用域中,几乎可以不受限制的使用。


编译器在遇到一个static_assert语句时,通常立刻将其第一个参数作为常量表达式进行演算,但如果该常量表达式依赖于某些模板参数,则延迟到模板实例化时再进行演算,这就让检查模板参数成为了可能。


由于是static_assert编译期间断言,不生成目标代码,因此static_assert不会造成任何运行期性能损失。


注意事项


注意:static_assert的断言表达式的结果必须是在编译时期可以计算的表达式,即必须是常量表达式。如果使用变量,则会导致错误。


int positive(const int n) {
    static_assert(n > 0, "value must > 0");
    return 0;
}



代码案例


检查模板参数示例


这里使用assert运行时断言,但如果bit_copy不被调用,我们将无法触发该断言,实际上正确产生断言的时机应该在模版实例化时,即编译时期。




#include <stdio.h>
#include <cassert>
#include <cstring>
template <typename T, typename U> int bit_copy(T& a, U& b){
    assert(sizeof(b) == sizeof(a));  //static_assert(sizeof(b) == sizeof(a), "template parameter size no equal!");
    memcpy(&a,&b,sizeof(b));
};
int main()
{
    int aaa = 0x2468;
    double bbb;
    bit_copy(aaa, bbb);
    getchar();
    return 0;
}
相关文章
|
5月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
231 0
|
9月前
|
安全 编译器 程序员
C++ noexcept 关键字的关键作用
`noexcept` 关键字在 C++ 中扮演着重要角色,通过正确使用 `noexcept`,可以提升程序的性能、增强代码的可读性和安全性,并且有助于编译器进行优化。在编写 C++ 代码时,应仔细考虑每个函数是否应该声明为 `noexcept`,以充分利用这一特性带来的优势。通过本文的介绍,希望开发者能够更好地理解和应用 `noexcept` 关键字,从而编写出更加高效、健壮的 C++ 程序。
309 8
|
11月前
|
安全 编译器 C++
C++ `noexcept` 关键字的深入解析
`noexcept` 关键字在 C++ 中用于指示函数不会抛出异常,有助于编译器优化和提高程序的可靠性。它可以减少代码大小、提高执行效率,并增强程序的稳定性和可预测性。`noexcept` 还可以影响函数重载和模板特化的决策。使用时需谨慎,确保函数确实不会抛出异常,否则可能导致程序崩溃。通过合理使用 `noexcept`,开发者可以编写出更高效、更可靠的 C++ 代码。
|
存储 安全 编译器
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(一)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值
203 1
|
存储 编译器 程序员
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(二)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值
156 0
|
存储 安全 编译器
C++入门 | auto关键字、范围for、指针空值nullptr
C++入门 | auto关键字、范围for、指针空值nullptr
280 4
|
存储 安全 编译器
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
|
存储 安全 编译器
【C++航海王:追寻罗杰的编程之路】引用、内联、auto关键字、基于范围的for、指针空值nullptr
【C++航海王:追寻罗杰的编程之路】引用、内联、auto关键字、基于范围的for、指针空值nullptr
174 5
|
存储 编译器 程序员
C++一分钟之-auto关键字与类型推导
【6月更文挑战第21天】`auto`在C++11中重生,简化了类型声明,尤其在处理复杂类型时。它让编译器根据初始化值推导变量类型,减少了冗余和错误。使用`auto`简化了迭代器声明和函数返回类型推导,但也带来挑战:类型推导可能不直观,未初始化的`auto`是错误的,且过度使用影响可读性。使用`auto&`和`auto*`明确引用和指针,`decltype`辅助复杂类型推导,保持适度使用以维持代码清晰。
182 1
|
编译器 C语言 C++
【C++关键字】指针空值nullptr(C++11)
【C++关键字】指针空值nullptr(C++11)