Reputation: 747
I have a few static asserts in different places in code.
static_assert(bool_constexpr_1, error_message);
...
static_assert(bool_constexpr_2, error_message);
And want all of them to share the same error_message
.
The first solution is to copy-paste the message.
The second one is to #define
the error_message
.
Is there something better?
P.S. I expected static constexpr auto
to work, yet it failed.
Upvotes: 3
Views: 1277
Reputation: 11317
Your question sounds a lot like a variation: How to make static_assert block re-usable in template classes?
You have defined it a bit to generic, however, as you want to reuse the same 'error' message, I would assume that your check will also be similar. Let's use an example where you want to force inheritance:
struct Interface {};
struct Impl : Interface {};
struct Other {};
static_assert(std::is_base_of_v<Interface, Impl>, "Implementations should inherit from the interface. See document at ... for more details."); // Success
static_assert(std::is_base_of_v<Interface, Other>, "Implementations should inherit from the interface. See document at ... for more details."); // Failure
Here, it might make sense to implement your own type trait. For example:
template<typename T> using FrameworkInjectionRequirement = std::is_base_of<Interface, T>
template<typename T> constexpr bool FrameworkInjectionRequirement_v = FrameworkInjectionRequirement<T>::value;
static_assert(FrameworkInjectionRequirement_v<Impl>);
By doing this, you already gave a good name to what you try to check, which could be sufficient in order to use the terse version of static_assert instead, without needing an explanation.
Alternatively, you could wrap you assert into a struct:
template<typename T>
struct FrameworkInjectionRequirement {
static_assert(std::is_base_of_v<Interface, T>, "Implementations should inherit from the interface. See document at ... for more details.");
};
constexpr static FrameworkInjectionRequirement<Impl> check{}; // Success
constexpr static FrameworkInjectionRequirement<Other> check{}; // Failure
By instantiating this zero-size struct at compile time (thanks to constexpr
on the variable), the assert will be checked.
Not only can you reuse the message into it, you again gave your check a good name. As a bonus, you can split up the different elements creating the boolean expression into it's distinct elements, which will assist you if one of them fails.
Upvotes: 3
Reputation: 180945
You either have to copy-paste the literal, or use the preprocessor. Per [dcl.dcl]/1 The grammar of static_assert
is defined as
static_assert-declaration: static_assert ( constant-expression ) ; static_assert ( constant-expression , string-literal ) ;
So you either provide a string literal, or you don't. There is no other way to use it.
Upvotes: 5