【发布时间】:2014-11-03 13:38:38
【问题描述】:
考虑代码:
#include <type_traits>
struct CByteArray {};
struct HLVariant {
HLVariant() {}
HLVariant(const HLVariant&) {}
HLVariant(const CByteArray&) {}
};
template <typename T>
inline CByteArray serialize(const typename std::enable_if<true, T>::type& value)
{
return serialize(HLVariant(value));
}
template <typename T>
inline CByteArray serialize(const typename std::enable_if<false, T>::type& value)
{
return CByteArray();
}
template <>
inline CByteArray serialize(const HLVariant& value)
{
return CByteArray();
}
int main()
{
serialize(0);
serialize(CByteArray());
serialize(HLVariant());
return 0;
}
Microsoft Visual Studio 2013 给出以下错误:
C2912:显式特化 'CByteArray serialize(const HLVariant &)' 不是函数模板的特化
错误 C2783:'CByteArray 序列化(常量 std::enable_if::type &)' : 无法推断出 'T' 的模板参数
错误表明编译器看不到template <typename T> CByteArray serialize(const T&); 函数,我不明白为什么。请注意,我只是将true 和false 用于enable_if 条件,用于此处的测试目的。
我也尝试过这种方式(enable_if 返回类型而不是参数):
template <typename T>
inline typename std::enable_if<true, CByteArray>::type serialize(const T& value)
{
return serialize(HLVariant(value));
}
template <typename T>
inline typename std::enable_if<false, CByteArray>::type serialize(const T& value)
{
return CByteArray();
}
现在的错误是:
C2039: 'type' : is not a member of 'std::enable_if<false,CByteArray>'
【问题讨论】:
-
我想如果你用结构专业化来做它会起作用的......(正在努力)
-
对于 SFINAE,条件应取决于模板参数。
-
template <> inline CByteArray serialize(const HLVariant& value)由于您没有明确指定模板参数,编译器将不得不推断它们(从函数参数类型)。但这是不可能的,因为对于两个serialize模板,T处于非推断上下文中。 -
std::enable_if<false, CByteArray>::type由于没有依赖于模板参数的类型,所以这里没有进行替换,因此替换时不会发生错误(=> 硬错误,没有 SFINAE)。