我正在使用一些 SFINAE 功能;当前位于必须在 Linux 和 Windows 中运行的应用程序的一部分中;编译器选择是用于 Windows 应用程序的 MSVC (Visual Studio 2010 10.0) 和用于 Linux 应用程序的 GCC 4.4.5。
我必须检查某个给定对象是否提供了一些函数来执行自定义序列化并调用此函数,或者在未提供自定义序列化方法的情况下执行简单的memcpy
操作。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
s 或放错词,但我不明白为什么我会收到错误并且不理解错误。
我知道 MSVC 的标准松懈,而 GCC 非常符合标准,所以我想知道问题是否出在允许愚蠢代码的 MSVC 方面!
以下是问题:
- 为什么我在?中收到
invalid parameter type 'void'
错误消息。struct sMemberMethodChecker
- 为什么代码在 MSVC 中有效但在 GCC 中无效?
- 这个代码是非标准的吗?
- SFINAE 诡计是 C++11 独有的吗?