I am trying to get static_assert to help me avoid null pointers in C++11.
The problem seems to be that C++11 require the compiler to compile templates even if they a
The standard permits, but does not require, compilers to diagnose templates for which no valid instantiation can be generated. This can range from simple syntax errors to your example of a constant false
expression in a static_assert
. §14.6 [temp.res]/p8:
If no valid specialization can be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic required.
I'm rather baffled by all this SFINAE machinery, though. A simple
template
T* create_if_constructible(Us... args) { return new T(args...); }
already refuses to compile if T
is not constructible from the parameter given, so I'm not sure how this complex circumlocution will help you "avoid null pointers".
Regardless, a simple way to make choosing the second function template a compile-time error is to explicitly delete it.
template
std::enable_if_t< std::is_constructible::value == false, T * >
create_if_constructible(Us... args) = delete;
Alternatively, if you are partial to static_assert
s, perhaps because of the custom error message, you must ensure that there is theoretically a way to generate a valid instantiation of your template. That means that 1) what you are static_assert
ing on must depend on a template argument, and 2) there must be theoretically a way for the condition to be true
. A simple way is to use an auxiliary template:
template class always_false : std::false_type {};
template
std::enable_if_t< std::is_constructible::value == false, T * >
create_if_constructible(Us... args) {
static_assert( always_false::value, "Class T constructor does not match argument list.");
return nullptr;
}
The key point here is that the compiler cannot assume that always_false
is always false
because it is always possible that there's a specialization later that sets it to true
, and so it is not allowed to reject this at template definition time.