问题描述
以下代码
#include <type_traits>
struct CByteArray {};
struct HLVariant {
HLVariant() {}
HLVariant(const HLVariant&) {}
HLVariant(const CByteArray&) {}
};
template <typename T>
inline typename std::enable_if<!std::is_pod<T>::value, CByteArray>::type serialize(const T& value)
{
return serialize(HLVariant(value));
}
template <typename T>
inline typename std::enable_if<std::is_pod<T>::value, CByteArray>::type serialize(const T& value)
{
return CByteArray();
}
template <>
inline CByteArray serialize(const HLVariant& value)
{
return CByteArray();
}
int main()
{
serialize(0);
serialize(CByteArray());
serialize(HLVariant());
return 0;
}
触发编译错误 C2794:'type':不是MSVC 2013中的'std :: enable_if< false,CByteArray>'
的任何直接或间接基类的成员。但是,它在ideone中工作:
triggers a compilation error C2794: 'type' : is not a member of any direct or indirect base class of 'std::enable_if<false,CByteArray>'
in MSVC 2013. It does, however, work in ideone: enter link description here
这里有什么错误?
错误在MSVC 2010,2012和2013中是一样的。
The error is the same in MSVC 2010, 2012 and 2013.
推荐答案
,但我可以通过从 serialize
的最后重载中删除模板<>
来修复它。当正常的重载时,不需要做一个完全的专门化。
It looks ok to me, but I can fix it by removing the template<>
from the final overload of serialize
. No need to make it a full specialisation when a normal overload will do!
编辑:还有什么工作是提供模板专门化,只匹配 HLVariant
(并进一步限制其他专业化不再匹配 HLVariant
,以避免歧义)。
What else works is providing a template specialisation which matches only HLVariant
(and further restricting the other specialisations to no longer match HLVariant
, to avoid ambiguity).
这应该可以:
#include <type_traits>
#include <iostream>
struct CByteArray {};
struct NonPod {public: int a; private: int b;};
struct HLVariant {
HLVariant() {}
HLVariant(const HLVariant&) {}
HLVariant(const CByteArray&) {}
HLVariant(const NonPod&) {}
};
template <typename T>
inline typename std::enable_if<std::is_same<T, HLVariant>::value && !std::is_pod<T>::value, CByteArray>::type serialize(const T& value)
{
std::cout << "serialize non-pod variant\n";
return CByteArray();
}
template <typename T>
inline typename std::enable_if<!std::is_same<T, HLVariant>::value && !std::is_pod<T>::value, CByteArray>::type serialize(const T& value)
{
std::cout << "serialize non-pod non-variant\n";
return serialize(HLVariant(value));
}
template <typename T>
inline typename std::enable_if<std::is_pod<T>::value, CByteArray>::type serialize(const T& value)
{
std::cout << "serialize pod\n";
return CByteArray();
}
int main()
{
std::cout << "int:\n";
serialize(0);
std::cout << "CByteArray:\n";
serialize(CByteArray());
std::cout << "HLVariant:\n";
serialize(HLVariant());
std::cout << "NonPod:\n";
serialize(NonPod());
}
这篇关于对模板函数使用std :: enable_if返回类型以利用SFINAE - 编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!