"Conversion" 从类型到相同类型导致错误
"Conversion" from type to same type is causing error
我有一个模板函数,其中枚举类型转换为它的底层类型,工作正常,但我写了一个重载,它应该采用整数和 return 本身,它给我一个 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>::type
正在 std::enable_if
中计算,即使 std::is_enum<TT>::value
是 false
,因为 false
不是错误。由于正在评估非枚举类型,因此它会导致错误。如果我们将 SFINAE 移动到模板参数中,我们可以获得所需的重载并且仍然 return 正确的类型。
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;
}
你可以看到它在这个 Live Example
中工作
通过尝试使用非枚举类型的 T
实例化 std::underlying_type<T>
,您违反了标准对模板参数 T
:
的要求
§ 20.10.7.6 [meta.trans.other]/Table 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
,因为嵌套的 type
定义被请求用于 std::enable_if<B,T>::type
returns.
我有一个模板函数,其中枚举类型转换为它的底层类型,工作正常,但我写了一个重载,它应该采用整数和 return 本身,它给我一个 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>::type
正在 std::enable_if
中计算,即使 std::is_enum<TT>::value
是 false
,因为 false
不是错误。由于正在评估非枚举类型,因此它会导致错误。如果我们将 SFINAE 移动到模板参数中,我们可以获得所需的重载并且仍然 return 正确的类型。
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;
}
你可以看到它在这个 Live Example
中工作通过尝试使用非枚举类型的 T
实例化 std::underlying_type<T>
,您违反了标准对模板参数 T
:
§ 20.10.7.6 [meta.trans.other]/Table 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
,因为嵌套的 type
定义被请求用于 std::enable_if<B,T>::type
returns.