我正在使用 SFINAE 的一些功能;当前位于必须在 Linux 和 Windows 中运行的应用程序的一部分; Windows 应用程序的编译器选择是 MSVC (Visual Studio 2010 10.0),Linux 应用程序的编译器选择是 GCC 4.4.5。
我必须检查某个给定对象是否提供了一些函数来执行自定义序列化并调用此函数,或者执行一个简单的操作memcpy
and sizeof(Object)
而没有提供自定义序列化方法。
问题在于,一段代码在 MSVC 中编译时没有警告或错误,但在使用 GCC 编译时,代码如下:
template
<
typename Type,
typename Return,
typename Parameter,
Return (Type::*Pointer)(Parameter) const
> struct sMemberMethodConst { };
template
<
typename Type,
typename Return,
typename Parameter,
Return (Type::*)(Parameter)
> struct sMemberMethod { };
template<typename T> struct sMemberMethodChecker
{
template <typename Type> static char HasCustomSizeMethod(sMemberMethodConst<Type, size_t, void, &Type::Size> *);
template <typename Type> static long HasCustomSizeMethod(...);
template <typename Type> static char HasSerializeMethod(sMemberMethodConst<Type, size_t, void * const, &Type::Serialize> *);
template <typename Type> static long HasSerializeMethod(...);
template <typename Type> static char HasDeserializeMethod(sMemberMethod<Type, size_t, const void * const, &Type::Deserialize> *);
template <typename Type> static long HasDeserializeMethod(...);
// Other specific method checks...
enum
{
HAS_CUSTOM_SIZE_METHOD = (sizeof(HasCustomSizeMethod<T>(0)) == sizeof(char)),
HAS_SERIALIZE_METHOD = (sizeof(HasSerializeMethod<T>(0)) == sizeof(char)),
HAS_DESERIALIZE_METHOD = (sizeof(HasDeserializeMethod<T>(0)) == sizeof(char)),
IS_CUSTOM = HAS_CUSTOM_SIZE_METHOD &&
HAS_SERIALIZE_METHOD &&
HAS_DESERIALIZE_METHOD,
// Other 'shortcuts'...
};
我在使用 GCC 编译时遇到的错误是:
invalid parameter type 'void' in declaration template<class Type, class Return, class Parameter, Return (Type::* Pointer)(Parameter)const>
在第一行struct sMemberMethodChecker
。我很确定我没有失踪typename
也没有放错单词,但我不明白为什么我会收到错误并且不理解该错误。
我知道MSVC对标准不严格,而GCC则很好地符合标准,所以我想知道问题是否出在允许的MSVC方面愚蠢的代码!
以下是问题:
- 为什么我得到
invalid parameter type 'void'
错误在struct sMemberMethodChecker
?.
- 为什么代码在 MSVC 中有效但在 GCC 中无效?
- 这段代码是非标准的吗?
- SFINAE 诡计是 C++11 独有的吗?