Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should static_assert be triggered with a typedef?

I noticed that static assertions in class templates are not triggered when instantiations are typedef'ed.

#include <type_traits>

template <typename T>
struct test_assert
{
    static_assert( std::is_same< T, int >::value, "should fail" );
};

typedef test_assert< float > t;

This code compiles without error. If I try to create an instance, then the assertion fails:

t obj; // error: static assertion failed: "should fail"

Finally, if I replace the condition with false, the assertion fails even if I don't instantiate the class template:

template <typename T>
struct test_assert
{
    static_assert( false, "always fails" );
};

I tried this code on gcc-4.5.1 and gcc-4.7.0. Is this behavior normal? At what time is the compiler supposed to verify static assertions? I guess two-phase lookup is involved, but shouldn't the typedef trigger the second phase?

like image 683
Luc Touraille Avatar asked Jun 28 '12 19:06

Luc Touraille


1 Answers

I tried this code on gcc-4.5.1 and gcc-4.7.0. Is this behavior normal?

Yes

At what time is the compiler supposed to verify static assertions?

This is an interesting question. During instantiation, which will be first phase lookup for non-dependent names and second lookup phase for asserts that depend on template arguments.

guess two-phase lookup is involved, but shouldn't the typedef trigger the second phase?

Templates are compiled on demand, the typedef just creates an alias to the template and does not trigger the instantiation. Consider the following code:

template <typename T> class unique_ptr;
typedef unique_ptr<int> int_unique_ptr;

The template is only declared, but that suffices for the typedef, as it only generates an alias for the type. On the other side, if you create an object of the type, then the template must be instantiated (again on demand, member functions will not be instantiated).

like image 88
David Rodríguez - dribeas Avatar answered Oct 10 '22 02:10

David Rodríguez - dribeas