如何查找类中是否存在特定原型的方法?

2024-01-06

我正在使用 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 独有的吗?

为什么我在结构中收到无效参数类型“void”错误 sMemberMethodChecker?

为什么代码在 MSVC 中有效但在 GCC 中无效?

我相信 MSVC 很有帮助,但 GCC 在这个特定代码中非常严格。因为它不知何故不允许Return (Type::*)(void)。然而,人们需要进一步挖掘才能知道确切的原因。

这段代码不标准吗?

在无法编译之前不能说。并不是每个人都喜欢寻找 SFINAE 等功能的标准。

SFINAE 诡计是 C++11 独有的吗?

一点也不。 SFINAE 在 C++11 之前就已存在。
这里是简化的你想做的事情的方式:

template<typename ClassName, typename ClassMethodType>
struct HasMethod
{
  template<typename Type, Type Object> struct Contains;
  typedef char (&yes)[2];

  template<typename Class, typename MethodType>
  static yes Check (Contains<MethodType, &Class::size>*);
  template<typename Class, typename MethodType>
  static char Check (...);

  static const bool value = (sizeof(Check<ClassName,ClassMethodType>(0)) == sizeof(char));
};

HasMethod<ClassName, ClassMethodType>::value给你答案是否存在某种类型的成员方法。
截至目前HasMethod<>是独家的方法命名 size与用户提供的类型。但是您可以为上面的代码创建一个宏并使函数名称可配置.

这里有一个使用 g++ 进行工作演示 http://ideone.com/8W5wdT.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何查找类中是否存在特定原型的方法? 的相关文章

随机推荐