多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## BOOST_STATIC_ASSERT ### 头文件: `"boost/static_assert.hpp"` 在运行期执行断言可能是你经常用到的,也是非常合理的。它是测试前置条件、后置条件以及不变式的好方 法。执行运行期断言有很多不同的方法,但是在编译期你如何进行断言呢?当然,唯一的方法就是让编译器产生一个错误,这是很平常的事情(我在无意中都做过几 千次了),但如何从错误信息中获得有意义的信息却不是那么明显的。而且,即使你在一个编译器上找到了办法,也很难把它移植到其它编译器上。这就是使用 `BOOST_STATIC_ASSERT`的原因。它可以在不同的平台上使用,正如我们即将看到的。 ### 用法 要开始使用静态断言,就要包含头文件 `"boost/static_assert.hpp"`. 该头文件定义了宏\[2\] `BOOST_STATIC_ASSERT`. 作为它的第一个使用范例,我们来看看如何在类作用域中使用它。考虑一个泛化的类,它要求实例化时所用的类型是一个整数类型。我们不想为所有类型提供特化, 因此我们需要在编译期进行测试,以确保我们的类的确是用一个整数类型进行实例化的。现在,我们先提前一点使用另一个Boost库来进行测试,它就是 Boost.Type_traits. 我们使用一个称为`is_integral`的断言,它对它的参数执行一个编译期求值,正如你从它的名字可以猜到的一样,求值的结果是表明该类型是否一个整数类型。 > \[2\] 是的,它是一个宏。你知道,宏也可以很有用的。 ``` #include <iostream> #include "boost/type_traits.hpp" #include "boost/static_assert.hpp" template <typename T> class only_compatible_with_integral_types { BOOST_STATIC_ASSERT(boost::is_integral<T>::value); }; ``` 有了这个断言,在实例化类 `only_compatible_with_integral_types` 时如果试图使用一个非整型的类型,就会导致一个编译期的失败。输出信息取决于编译器,但在多数编译器下输出信息会惊人地一致。 假设我们试图这样实例化: ``` only_compatible_with_integral_types<double> test2; ``` 编译器将会有类似下面的输出: ``` Error: use of undefined type 'boost::STATIC_ASSERTION_FAILURE<false>' ``` 在类的作用域里,你可以明确类的要求:象在前面这样的模板中明确参数的类型就是一个明显的例子。你也可以使用断言来明确类所要求的其它前提条件,如类型的大小等等。 ### 函数作用域中的BOOST_STATIC_ASSERT  `BOOST_STATIC_ASSERT` 也可以用在函数作用域中。例如,考虑一个泛化的函数,它带有一个非类型模板参数,并且该参数只接受1至10的值。与其在运行期执行断言,我们不如在编译器使用静态断言。 ``` template <int i> void accepts_values_between_1_and_10() { BOOST_STATIC_ASSERT(i>=1 && i<=10); } ``` 该函数的用户不能使用超出允许范围的数值来实例化这个函数。当然,断言中的表达式必须是一个纯粹的编译期表达式,也就是说,表达式中的参数和操作符都必须被编译器所认识。`BOOST_STATIC_ASSERT` 当然并不是只能用于泛型函数;我们可以在任何函数中很方便地测试条件。例如,一个函数需要一个与平台相关的前提条件,就常常需要一个断言。 ``` void expects_ints_to_be_4_bytes() { BOOST_STATIC_ASSERT(sizeof(int)==4); } ``` ### 总结 你所看到的这种静态断言在C++中正变得象运行期断言`assert`那样常用。这应该至少部分地归功于"元编程革命",它使得一个程序中更多的计算量在编译期执行。表达编译期断言的唯一方法就是让编译器产生一个错误。为了让断言可用,错误提示必须可以传达有用的信息,但这很难做到可移植(事实上,根本不可能做到)。这正是 `BOOST_STATIC_ASSERT` 所要做的,它在大多数的编译器下提供了编译期断言的一致输出。它可用于名字空间、类、函数以及作用域。 以下情形下使用 `BOOST_STATIC_ASSERT` : * 当条件可以在编译期进行求值 * 对类型的要求可以在编译期表示 * 你需要对两个或以上的整型常量间的关系进行断言