Why does static_assert need to be out side of the class definition?
Failing code
#include <type_traits> class A { public: A(A&&) noexcept {} static_assert(std::is_nothrow_move_constructible<A>::value, "ERROR"); }; int main() { }
Working code
#include <type_traits> class A { public: A(A&&) noexcept {} }; static_assert(std::is_nothrow_move_constructible<A>::value, "ERROR"); int main() { }
And when is it appropriate to use static_asserts in the definition of a class or struct?
static_assert is a keyword defined in the <assert. h> header. It is available in the C11 version of C. static_assert is used to ensure that a condition is true when the code is compiled.
If the condition is true, the static_assert declaration has no effect. If the condition is false, the assertion fails, the compiler displays the message in string_literal parameter and the compilation fails with an error.
As far as the placement of static_assert
itself is concerned both versions of your code are valid. So, no, static_assert
does not need to be outside of class definition. Formally static_assert
is a declaration. It is allowed wherever declarations are allowed.
The problem you are having has nothing to do with static_assert
itself.
The problem here is that the expression that you use as the argument of your static_assert
(std::is_nothrow_move_constructible
) requires the class type to be complete to work properly. But inside the definition of class A
class type A
is not complete yet, which makes your argument expression invalid. This is why your static_assert
works as intended only outside the class definition, where A
is complete. However, this is entirely about proper usage of std::is_nothrow_move_constructible
, not about static_assert
itself.
Note, that inside member function bodies class type is seen in its entirety, as complete type, even if the member function is defined inside the class definition. Using this feature you can rewrite your code as
class A { public: A(A&&) noexcept { static_assert(std::is_nothrow_move_constructible<A>::value, "ERROR"); } };
and std::is_nothrow_move_constructible<A>
will produce the proper result.
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