Я работаю с некоторыми функциями 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
, Я совершенно уверен, что я не скучаю typename
s и неуместные слова, но я не понимаю, почему я получаю ошибку и не понимает ошибку.
Я знаю, что MSVC неэффективен со стандартом, в то время как GCC соответствует стандарту довольно хорошо, поэтому мне интересно, заключается ли проблема в стороне MSVC, которая позволяет глупый код!
Вот вопросы:
invalid parameter type 'void'
ошибка в struct sMemberMethodChecker
?.Почему я получаю неверную ошибку типа параметра ‘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
с предоставленным пользователем типом. Но вы можете создать макрос для приведенного выше кода и сделать имя функции настраивается.
Других решений пока нет …