I am reading the machine learning library dlib which is written in C++. I came across a code in a header file which defines a bunch of macros. I have difficulties understanding the following code
#ifndef BOOST_JOIN
#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y )
#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y)
#define BOOST_DO_JOIN2( X, Y ) X##Y
#endif
// a bunch of other code
namespace dlib
{
template <bool value> struct compile_time_assert;
template <> struct compile_time_assert<true> { enum {value=1}; };
// a bunch of other definitions
}
#define COMPILE_TIME_ASSERT(expression) \
DLIB_NO_WARN_UNUSED typedef char BOOST_JOIN(DLIB_CTA, __LINE__)[::dlib::compile_time_assert<(bool)(expression)>::value]
what I do not understand is that
what does the last line in the above code do?
typedef char
here is so weird, I don't understand it at all.
BOOST_JOIN
, it becomes DLIB_CTA__LINE__[1]
, why it is an array? Is it legal? This is a C++03 static assert, or at least the workaround used to simulate it.
The following defines a struct only if value
is true, else the type is not defined.
template <bool value> struct compile_time_assert;
template <> struct compile_time_assert<true> { enum {value=1}; };
Which means compile_time_assert<true>::value
is perfectly correct, but compile_time_assert<false>::value
is a compilation error since compile_time_assert<false>
is not defined.
Now, the core of the assert:
DLIB_NO_WARN_UNUSED typedef char BOOST_JOIN(DLIB_CTA, __LINE__) ::dlib::compile_time_assert<(bool)(expression)>::value]
This defines a typedef on a char
array of size 1, only if expression
evaluates to true. If the expression evaluates to false, then there is a compile time error and the name of the typedef is a hint about the error.
Note that there are some variants of this. Some use a negative or null size instead of a compilation error, ie they define the following:
template <> struct compile_time_assert<false> { enum { value = -1 }; };
But actually there is a way concise formulation of this (you can see it in this question ):
typedef char static_assert_something[expression ? 1 : -1];
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.