从类型到相同类型的"Conversion"导致错误

"Conversion" from type to same type is causing error

本文关键字:Conversion 错误 类型 同类型      更新时间:2023-10-16

我有一个模板函数,其中枚举类型转换为其底层类型,工作良好,但我写了一个重载,它应该接受一个整数并返回它自己,它给我一个错误,int不是枚举类型。在我的模板中,这应该被过滤掉。怎么了?

模板代码如下:

  template <typename TT>
  static constexpr auto get_value(TT t)
    -> typename std::enable_if<!std::is_enum<TT>::value, TT>::type
    {
      return t;
    }
  template <typename TT>
  static constexpr auto get_value(TT t)
    -> typename std::enable_if<std::is_enum<TT>::value, typename std::underlying_type<TT>::type>::type
    {
      return (typename std::underlying_type<TT>::type)t;
    }

std::underlying_type<TT>::typestd::enable_if中被评估,即使std::is_enum<TT>::valuefalse,因为false不是错误。由于正在计算非枚举类型,因此会导致错误。如果我们将SFINAE移动到模板参数中,我们可以得到所需的重载,并且仍然返回正确的类型。

template <typename TT, typename std::enable_if<!std::is_enum<TT>::value, TT>::type* = nullptr>
static constexpr auto get_value(TT t) -> TT
{
    return t;
}
template <typename TT, typename std::enable_if<std::is_enum<TT>::value>::type* = nullptr>
static constexpr auto get_value(TT t) -> typename std::underlying_type<TT>::type
{
    return (typename std::underlying_type<TT>::type)t;
}

你可以看到它在这个实例

中工作

试图用非枚举类型的T实例化std::underlying_type<T>,您违反了标准对模板参数T的要求:

§20.10.7.6 [meta.trans.]其他)/表57:

       Template         |         Condition         |       Comments
------------------------+---------------------------+-----------------------
template <class T>      | T shall be an enumeration | The member typedef
struct underlying_type; | type (7.2)                | type shall name
                        |                           | the underlying type 
                        |                           | of T.

如果不喜欢任何额外的模板参数,这里有一个替代方法:

template <typename TT>
static constexpr auto get_value(TT t)
    -> typename std::enable_if<!std::is_enum<TT>::value, TT>::type
{
    return t;
}
template <typename TT>
static constexpr auto get_value(TT t)
    -> typename std::enable_if<std::is_enum<TT>::value
                             , std::underlying_type<TT>
                >::type::type
{
    return (typename std::underlying_type<TT>::type)t;
}

这样,std::underlying_type<TT>的实例化被延迟,直到std::enable_if中的条件求值为true,因为std::enable_if<B,T>::type返回的值需要一个嵌套的type定义。

相关文章: