Problem
The following does not build because the message is not a string-literal.
template<typename T>
struct Foo
{
Foo()
{
static_assert( is_pod<T>::value, typeid(T).name() );
}
};
Ultimately, I would like a failure message like "Bar must be a pod-type", if I try to compile Foo<Bar> fb;
.
Is it possible to build this string during compile-time, as required by 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)
Inside templates, you get what Daniel Frey's has explained. Outside templates, this isn't possible with static_assert
alone but can be accomplished with the help of a macro and the stringification operator #
:
#define VERIFY_POD(T) \
static_assert(std::is_pod<T>::value, #T " must be a pod-type" );
For the type struct non_pod { virtual ~non_pod() {} };
with gcc 4.8.1, VERIFY_POD(non_pod)
gives
main.cpp:4:2: error: static assertion failed: non_pod must be a pod-type
static_assert(std::is_pod<T>::value, #T " must be a pod-type" );
^
main.cpp:15:2: note: in expansion of macro 'VERIFY_POD'
VERIFY_POD(non_pod);
If you're like me and don't want to see the tokens #T " must be a pod-type"
in the error message, then you can add an extra line to the macro definition:
#define VERIFY_POD(T) \
static_assert(std::is_pod<T>::value, \
#T "must be a pod-type" );
with this, the previous example yields:
main.cpp: In function 'int main()':
main.cpp:4:2: error: static assertion failed: non_pod must be a pod-type
static_assert(std::is_pod<T>::value, \
^
main.cpp:14:2: note: in expansion of macro 'VERIFY_POD'
VERIFY_POD(non_pod);
^
Of course, the exact look of the error message depends on the compiler. With clang 3.4 we get
main.cpp:14:5: error: static_assert failed "non_pod must be a pod-type"
VERIFY_POD(non_pod);
^~~~~~~~~~~~~~~~~~~
main.cpp:3:23: note: expanded from macro 'VERIFY_POD'
#define VERIFY_POD(T) \
^
1 error generated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With