Integrate Type Name in Static_Assert Output

How do I embed a type's name as a string into a static_assert()?

It's not possible to build the required string at compile time and to put it in the message, but this is usually not a problem in practice as the error message will contain the calling context and you can always create a wrapper for your static_assert which shows the type in the error message:

template< typename T >
void verify_pod()
{
static_assert( std::is_pod<T>::value, "T is not a POD" );
}

yields

clang++ -std=c++11 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp:7:5: error: static_assert failed "T is not a POD"
static_assert( std::is_pod<T>::value, "T is not a POD" );
^ ~~~~~~~~~~~~~~~~~~~~~
main.cpp:12:5: note: in instantiation of function template specialization 'verify_pod<std::basic_string<char> >' requested here
verify_pod< std::string >();
^
1 error generated.

Note the note: ... where the wrapper with the type std::string (or here: std::basic_string<char>) is shown.

Live example (Clang)

For GCC, the error message is also very nice:

main.cpp: In instantiation of 'void verify_pod() [with T = std::basic_string<char>]':
main.cpp:12:31: required from here
main.cpp:7:5: error: static assertion failed: T is not a POD
static_assert( std::is_pod<T>::value, "T is not a POD" );
^

Live example (GCC)

C static_assert first parameter

A static_assert happens at compile time, but the decision in an if statement happens at run time. The compiler cannot know that the if clause will be false, and it needs to look at the body of the if statement to know what to do if it isn’t. It sees a static assert, which fails, so generates a compilation error.

C++11 static_assert: Parameterized error messages

You cannot do this. static_assert wants a string literal. You have no way to assemble the semantic identity of T and Y into the string literal.

You can hope that the compiler gives an easy to read backtrace of the template instantiation stack and gives you the value of T and Y template parameters of the enclosing class template instantiation.

Other people thought about this too, see http://comments.gmane.org/gmane.comp.compilers.clang.devel/5073 for example.

static_assert of class template parameter

The only real requirement of using static_assert is that the expression used must be a constant expression (i.e. the value must be determinable at compile-time), so you will run into an issue if you attempt to use a value that is not known until run-time.

So as long as the values you use are compile-time constants you should be fine.

Force static_assert to fire during type instantiating

One suggestion

template <int I>
struct foo_guard {
static_assert(I < 5, "I must be smaller than 5!");
typedef void type;
};
template < int I, typename = typename foo_guard<I>::type>
struct foo
{
};

Do static_assert on every other type in a template

Please try this:

#include <type_traits>

template <typename... Ts>
struct default_constructible;

template <typename T>
struct default_constructible<T>
{
static constexpr bool value = std::is_default_constructible<T>::value;
};

template <>
struct default_constructible<>
{
static constexpr bool value = true;
};

template <typename T, typename U, typename... Ts>
struct default_constructible<T, U, Ts...>
{
static constexpr bool value = std::is_default_constructible<T>::value && default_constructible<Ts...>::value;
};

template <typename... Ts>
struct foo
{
static_assert(default_constructible<Ts...>::value, "");
};

class A { A() = delete; };

template class foo<int, bool>; // Compiles
template class foo<int, bool, A>; // Does not compile

Demo



Related Topics



Leave a reply



Submit