我在代码的不同位置有一些静态断言。
static_assert(bool_constexpr_1, error_message);
...
static_assert(bool_constexpr_2, error_message);
并希望他们所有人共享相同的error_message
。
第一个解决方案是复制粘贴消息。
第二个是#define
error_message
。
还有更好的东西吗?
P.S。我期望static constexpr auto
可以工作,但是失败了。
答案 0 :(得分:4)
您要么复制粘贴文字,要么使用预处理器。根据{{3}},static_assert
的语法定义为
static_assert-declaration: static_assert ( constant-expression ) ; static_assert ( constant-expression , string-literal ) ;
因此,您要么提供字符串文字,要么不提供。没有其他方法可以使用它。
答案 1 :(得分:3)
您的问题听起来很像变体:How to make static_assert block re-usable in template classes?
您已经将其定义为泛型,但是,由于您想重用相同的“错误”消息,因此我认为您的检查也将类似。让我们使用一个示例,在其中您要强制继承:
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
在这里,实现自己的类型特征可能很有意义。例如:
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>);
通过这样做,您已经为要检查的内容起了一个好名字,这足以使用static_assert的简洁版本,而无需解释。
或者,您可以将断言包装到一个结构中:
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
通过在编译时实例化此零大小的结构(由于变量上的constexpr
),将检查断言。
您不仅可以重复使用邮件,还可以给支票起好名字。另外,您可以将创建布尔表达式的不同元素拆分为不同的元素,如果其中之一失败,将为您提供帮助。