This is a part of a static assert trick. I can’t understand how the unspecialized class works. Can someone explain it to me?
EDIT: Full code with macro: (taken from http://www.skynet.ie/~caolan/Fragments/C++StaticAssert.html)
#ifndef STATICASSERT_HXX
#define STATICASSERT_HXX
/*
Lifted direct from:
Modern C++ Design: Generic Programming and Design Patterns Applied
Section 2.1
by Andrei Alexandrescu
*/
namespace ww
{
template<bool> class compile_time_check
{
public:
compile_time_check(...) {}
};
template<> class compile_time_check<false>
{
};
}
/*
Similiar to assert, StaticAssert is only in operation when NDEBUG is not
defined. It will test its first argument at compile time and on failure
report the error message of the second argument, which must be a valid c++
classname. i.e. no spaces, punctuation or reserved keywords.
*/
#ifndef NDEBUG
# define StaticAssert(test, errormsg) \
do { \
struct ERROR_##errormsg {}; \
typedef ww::compile_time_check< (test) != 0 > tmplimpl; \
tmplimpl aTemp = tmplimpl(ERROR_##errormsg()); \
sizeof(aTemp); \
} while (0)
#else
# define StaticAssert(test, errormsg) \
do {} while (0)
#endif
#endif
The macro calls this code in a way similar to this:
So, for example, you could do this:
When
sizeof(Foo)is less thansizeof(Bar), the template would instanciate the unspecialized version:and the code basically "compiles to" an instanciation of this class:
which, being empty and doing nothing, the compiler can remove as dead code. Bam, no runtime overhead, done.
If, on the other hand,
sizeof(Foo)is greater than or equal tosizeof(Bar), it would instead instanciate the specialized version:and it would attempt to call the constructor
compile_time_check::compile_time_check(struct), but since it doesn’t exist, its a compile error. Which is what you want, because static assert should only compile if the assert is true.The reason for the constructor to take a variadic parameter list is, I believe, two-fold:
constructor not found for compile_time_check::compile_time_check(ERROR_Assertion_error_blah())perhaps.An alternative, template-free (I believe its often used in C), static assert I’ve seen somewhere before is this:
This works because if
predis false, the code would end up asswitch(0){case: 0: case 0:;}and two case labels with the same constant is an error. In depth explanation here.