【发布时间】:2015-12-04 07:07:41
【问题描述】:
我有一个模板函数,其中枚举类型转换为其基础类型,它工作正常,但我编写了一个重载,它应该采用整数并返回自身,它给我一个错误,即 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;
}
【问题讨论】:
-
我不知道
underlying_type是否对 SFINAE 友好,但有一个 workaround 可以解决这个问题 -
什么?我看到它起作用了,但是这里发生了什么使它起作用?为什么
underlying_typeby SFINAE 不友好? -
std::underlying_type<TT>::type的实例化被延迟,这样enable_if可以先失败。 SFINAE 友好我的意思是任何替换失败仅在直接上下文中发生(如果它发生在underlying_type本身内部,则它不是 SFINAE 友好的)。 -
@PiotrSkotnicki 不,它对 SFINAE 不友好,它有一个“条件”,即参数应为枚举类型 (=> UB)。
-
@Adrian SFINAE 是 Substitution Failure Is Not An Error 的首字母缩写词,但它命名的概念是 Substitution Failure In The Immediate Context 不是错误。这限制了编译器在替换期间必须能够检查模板中的类型的深度。例如,
template<class T> struct B : T {}; template<class T> B<T> foo();然后foo<int>将不会产生替换失败在直接上下文中(基类本身可以从其他类继承,最后一个深层嵌套发生错误)。
标签: c++ c++11 metaprogramming template-meta-programming