views:

165

answers:

4

This syntax was used as a part of an answer to this question:

template <bool>
struct static_assert;

template <>
struct static_assert<true> {}; // only true is defined

#define STATIC_ASSERT(x) static_assert<(x)>()

I do not understand that syntax. How does it work?

Suppose I do

STATIC_ASSERT(true);

it gets converted to

static_assert<true>();

Now what?

+1  A: 

Well, I guess it is about template specialization. STATIC_ASSERT(true) will compile successfully, because there is a definition (not just a declaration) of "static_assert< true >".

STATIC_ASSERT(false) will be rejected by the compiler, because there is only a declaration for "static_assert< false >" and no definition.

Update: for visual studio, STATIC_ASSERT(true) is ok, but STATIC_ASSERT(false) triggers the error: "error C2514: 'static_assert<__formal>' : class has no constructors [ with __formal = false ]"

SadSido
+9  A: 

static_assert<true>(); makes that

template <>
struct static_assert<true> {}

templated struct specialization temporary object creation being done - a call to constructor and later to a destructor that both will be hopefully eliminated by the optimizer since they do nothing. Since there's only a specialization for true and no generic version of the template struct all constructs that evaluate to static_assert<false>(); will just not compile.

sharptooth
Thank you for the explanation, i too found myself lost in this syntax.
PeterK
+3  A: 

In the expression

static_assert<true>();

since static_assert<true> is a type, it will call the constructor of static_assert<true>. As static_assert<true> is specialized to an empty struct, nothing will be affected.


However, in

static_assert<false>();

as there is no specialization for static_assert<false>, the generic definition

template <bool>
struct static_assert;

will be used. But here, the type static_assert<B> is incomplete. So calling constructor of static_assert<B> will result in compilation error.


Therefore, this is called "static assert" as the statement will abort the compilation if the expression evaluates to false, similar to the normal assert() function that will kill the program in runtime.

KennyTM
+9  A: 
STATIC_ASSERT(true);

indeed means

static_assert<true>();

which evaluates to nothing. static_assert<true> is just an empty structure without any members. static_assert<true>() creates an object of that structure and does not store it anywhere.

This simply compiles and does nothing.

On the other hand

STATIC_ASSERT(false);

means

static_assert<false>();

which results in compilation error. static_assert has no specialization for false. So a general form is used. But the general form is given as follows:

template <bool>
struct static_assert;

which is just a declaration of a structure and not its definition. So static_assert<false>() causes compilation error as it tries to make an object of a structure which is not defined.

Adam Badura
+1 Excellent explanation
fingerprint211b