Copyright ? 2000, 2005 Steve Cleary and John Maddock Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt ) Table of Contents This manual is also available in printer friendly PDF format.
The header
One of the aims of Illegal use of STATIC_ASSERTION_FAILURE<false> Which is intended to at least catch the eye!
You can use
The macro can be used at namespace scope, if there is some requirement must
always be true; generally this means some platform specific requirement.
Suppose we require that #include <climits> #include <cwchar> #include <limits> #include <boost/static_assert.hpp> namespace my_conditions { BOOST_STATIC_ASSERT(std::numeric_limits<int>::digits >= 32); BOOST_STATIC_ASSERT(WCHAR_MIN >= 0); } // namespace my_conditions
The use of the namespace my_conditions here requires some comment. The macro
The macro is typically used at function scope inside template functions, when the template arguments need checking. Imagine that we have an iterator-based algorithm that requires random access iterators. If the algorithm is instantiated with iterators that do not meet our requirements then an error will be generated eventually, but this may be nested deep inside several templates, making it hard for the user to determine what went wrong. One option is to add a static assertion at the top level of the template, in that case if the condition is not met, then an error will be generated in a way that makes it reasonably obvious to the user that the template is being misused. #include <iterator> #include <boost/static_assert.hpp> #include <boost/type_traits.hpp> template <class RandomAccessIterator > RandomAccessIterator foo(RandomAccessIterator from, RandomAccessIterator to) { // this template can only be used with // random access iterators... typedef typename std::iterator_traits< RandomAccessIterator >::iterator_category cat; BOOST_STATIC_ASSERT( (boost::is_convertible< cat, const std::random_access_iterator_tag&>::value)); // // detail goes here... return from; }
A couple of footnotes are in order here: the extra set of parenthesis around
the assert, is to prevent the comma inside the The macro is typically used inside classes that are templates. Suppose we have a template-class that requires an unsigned integral type with at least 16-bits of precision as a template argument, we can achieve this using something like this: #include <climits> #include <boost/static_assert.hpp> template <class UnsignedInt> class myclass { private: BOOST_STATIC_ASSERT((std::numeric_limits<UnsignedInt>::digits >= 16) && std::numeric_limits<UnsignedInt>::is_specialized && std::numeric_limits<UnsignedInt>::is_integer && !std::numeric_limits<UnsignedInt>::is_signed); public: /* details here */ }; Normally static assertions when used inside a class or function template, will not be instantiated until the template in which it is used is instantiated. However, there is one potential problem to watch out for: if the static assertion is not dependent upon one or more template parameters, then the compiler is permitted to evaluate the static assertion at the point it is first seen, irrespective of whether the template is ever instantiated, for example: template <class T> struct must_not_be_instantiated { BOOST_STATIC_ASSERT(false); }; Will produce a compiler error with some compilers (for example Intel 8.1 or gcc 3.4), regardless of whether the template is ever instantiated. A workaround in cases like this is to force the assertion to be dependent upon a template parameter: template <class T> struct must_not_be_instantiated { // this will be triggered if this type is instantiated BOOST_STATIC_ASSERT(sizeof(T) == 0); };
|