Как узнать, существует ли метод определенного прототипа внутри класса?

Я работаю с некоторыми функциями SFINAE; в настоящее время в части приложения, которое должно работать в Linux и Windows; выбор компилятора MSVC (Visual Studio 2010 10.0) для приложений Windows и GCC 4.4.5 для Linux.

Я должен проверить, предоставляет ли какой-то данный объект некоторые функции для выполнения пользовательской сериализации и вызвать эти функции, или сделать простое 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, Я совершенно уверен, что я не скучаю typenames и неуместные слова, но я не понимаю, почему я получаю ошибку и не понимает ошибку.

Я знаю, что MSVC неэффективен со стандартом, в то время как GCC соответствует стандарту довольно хорошо, поэтому мне интересно, заключается ли проблема в стороне MSVC, которая позволяет глупый код!

Вот вопросы:

  • Почему я получаю invalid parameter type 'void' ошибка в struct sMemberMethodChecker?.
  • Почему код действителен в MSVC, но недействителен в GCC?
  • Этот код нестандартный?
  • Обман SFINAE исключает C ++ 11?

5

Решение

Почему я получаю неверную ошибку типа параметра ‘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 ++.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector