如何将未明确的字符串文字错误消息传递给 static_assert?
How to pass a not explicitly string literal error message to a static_assert?
我在代码的不同地方有一些静态断言。
static_assert(bool_constexpr_1, error_message);
...
static_assert(bool_constexpr_2, error_message);
并希望所有人共享相同的 error_message
。
第一个解决方案是复制粘贴消息。
第二个是#define
error_message
.
还有更好的吗?
P.S。我希望 static constexpr auto
能工作,但它失败了。
您要么必须复制粘贴文字,要么使用预处理器。 Per [dcl.dcl]/1 static_assert
的语法定义为
static_assert-declaration:
static_assert ( constant-expression ) ;
static_assert ( constant-expression , string-literal ) ;
因此,您要么提供字符串文字,要么不提供。没有其他方法可以使用它。
你的问题听起来很像变体:
您已将其定义为通用的,但是,由于您想重复使用相同的 'error' 消息,我认为您的检查也将是相似的。让我们用一个你想强制继承的例子:
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
),将检查断言。
您不仅可以在其中重复使用该消息,而且您再次为您的支票取了一个好名字。作为奖励,您可以将创建布尔表达式的不同元素拆分为不同的元素,如果其中一个元素失败,这将对您有所帮助。
我在代码的不同地方有一些静态断言。
static_assert(bool_constexpr_1, error_message);
...
static_assert(bool_constexpr_2, error_message);
并希望所有人共享相同的 error_message
。
第一个解决方案是复制粘贴消息。
第二个是#define
error_message
.
还有更好的吗?
P.S。我希望 static constexpr auto
能工作,但它失败了。
您要么必须复制粘贴文字,要么使用预处理器。 Per [dcl.dcl]/1 static_assert
的语法定义为
static_assert-declaration: static_assert ( constant-expression ) ; static_assert ( constant-expression , string-literal ) ;
因此,您要么提供字符串文字,要么不提供。没有其他方法可以使用它。
你的问题听起来很像变体:
您已将其定义为通用的,但是,由于您想重复使用相同的 'error' 消息,我认为您的检查也将是相似的。让我们用一个你想强制继承的例子:
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
),将检查断言。
您不仅可以在其中重复使用该消息,而且您再次为您的支票取了一个好名字。作为奖励,您可以将创建布尔表达式的不同元素拆分为不同的元素,如果其中一个元素失败,这将对您有所帮助。