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
How to Call a Template Member Function
How to Get a List of Files in a Folder in Which the Files Are Sorted with Modified Date Time
What Is the Modern, Correct Way to Do Type Punning in C++
What Is Void* and to What Variables/Objects It Can Point To
What Is the Size of a Pointer? What Exactly Does It Depend On
Direct Boost Serialization to Char Array
Creating a String List and an Enum List from a C++ MACro
Resolving a Circular Dependency Between Template Classes
C++ Stack Trace from Unhandled Exception
Reading "Integer" Size Bytes from a Char* Array
What Is Wrong with Making a Unit Test a Friend of the Class It Is Testing
What's the Best Technique for Exiting from a Constructor on an Error Condition in C++
Quick Sort at Compilation Time Using C++11 Variadic Templates
What Is Allowed in a Constexpr Function
Ensuring C++ Doubles Are 64 Bits
Find Four Elements in Array Whose Sum Equal to a Given Number X