我如何静态地断言 static_cast 是 noexcept?
How do I statically assert that a static_cast is noexcept?
我有一个仿函数来执行从任何类型到特定类型的静态转换,定义如下:
template <typename T_Out>
struct cast_to {
template <typename T_In>
T_Out operator()(T_In&& value) const noexcept {
return static_cast<T_Out>(value);
}
};
现在,我想将仿函数的使用限制在那些隐式或显式声明为 noexcept
的静态转换表达式。这个想法是在 operator()
函数中添加一些静态断言。到目前为止,我已经尝试了两个 constexpr 表达式:
std::is_nothrow_constructible<T_Out, decltype(value)>::value
和
noexcept(static_cast<T_Out>(value))
两者似乎都按我的预期工作(实际上,我已经看到第一个检查也包括另一个,至少在 GCC 上是这样)。我应该更喜欢哪种方法?有更好的选择吗?
这取决于你想要达到的技术正确程度。正如您所说,这两个选项都达到了预期的目标——防止编译。区别是:
std::is_nothrow_constructible 测试将始终评估为真或假,使您的断言通过或失败。
noexcept 测试将评估为真、假,或者将无法编译内部 static_cast 检查您是否传递了根本不转换的参数。
我会选择以下其中一项:
- SFINAE 检查 std::is_nothrow_constructible
- SFINAE 检查 std::is_constructible,static_assert 是否没有例外
选项 2 可能有更好的诊断,但选项 1 在技术上可能更正确。个人喜好。
我有一个仿函数来执行从任何类型到特定类型的静态转换,定义如下:
template <typename T_Out>
struct cast_to {
template <typename T_In>
T_Out operator()(T_In&& value) const noexcept {
return static_cast<T_Out>(value);
}
};
现在,我想将仿函数的使用限制在那些隐式或显式声明为 noexcept
的静态转换表达式。这个想法是在 operator()
函数中添加一些静态断言。到目前为止,我已经尝试了两个 constexpr 表达式:
std::is_nothrow_constructible<T_Out, decltype(value)>::value
和
noexcept(static_cast<T_Out>(value))
两者似乎都按我的预期工作(实际上,我已经看到第一个检查也包括另一个,至少在 GCC 上是这样)。我应该更喜欢哪种方法?有更好的选择吗?
这取决于你想要达到的技术正确程度。正如您所说,这两个选项都达到了预期的目标——防止编译。区别是:
std::is_nothrow_constructible 测试将始终评估为真或假,使您的断言通过或失败。
noexcept 测试将评估为真、假,或者将无法编译内部 static_cast 检查您是否传递了根本不转换的参数。
我会选择以下其中一项:
- SFINAE 检查 std::is_nothrow_constructible
- SFINAE 检查 std::is_constructible,static_assert 是否没有例外
选项 2 可能有更好的诊断,但选项 1 在技术上可能更正确。个人喜好。