我如何静态地断言 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 检查您是否传递了根本不转换的参数。

我会选择以下其中一项:

  1. SFINAE 检查 std::is_nothrow_constructible
  2. SFINAE 检查 std::is_constructible,static_assert 是否没有例外

选项 2 可能有更好的诊断,但选项 1 在技术上可能更正确。个人喜好。