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.