c – 如何使用SFINAE创建相同方法的2种不同实现

前端之家收集整理的这篇文章主要介绍了c – 如何使用SFINAE创建相同方法的2种不同实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经阅读了一些关于SFINAE的文章,但找不到我的案例的解决方案.这就是我想要做的:
#include <type_traits>

struct CByteArray {};
struct HLVariant {
    HLVariant() {}
    HLVariant(const HLVariant&) {}
    HLVariant(const CByteArray&) {}

    };

template <typename T>
struct Serializer
{
    static inline typename std::enable_if<std::is_pod<T>::value,CByteArray>::type serialize(const T& value)
    {
        static_assert(std::is_pod<T>::value,"Not a POD type");
        return CByteArray();
    }

    static inline typename std::enable_if<!std::is_pod<T>::value,CByteArray>::type serialize(const T& value)
    {
        return Serializer<HLVariant>::serialize(HLVariant(value));
    }
};

template <>
struct Serializer<HLVariant>
{
    static inline CByteArray serialize(const HLVariant& value)
    {
        return CByteArray();
    }
};

int main()
{
    int i = 0;
    Serializer<int>::serialize(i);
    Serializer<CByteArray>::serialize(CByteArray());
    Serializer<HLVariant>::serialize(HLVariant());

    return 0;
}

但是,当然,我收到错误C2039:’type’:不是’std :: enable_if< false,CByteArray>‘的成员

如何实现我想要的?

此外,是否可以以某种方式重新组织串行器,以便可以隐式推导出模板参数 – Serializer :: serialize(i);而不是Serializer< int> :: serialize(i);?

解决方法

要使用std :: enable_if< condition>,您必须在条件的模板中.一种选择是声明辅助成员函数模板serialize_t
template <typename T>
struct Serializer
{
    template<bool is_pod>  // template over condition
    static typename std::enable_if< is_pod,CByteArray>::type serialize_t(const T& value)
    { return CByteArray(); }

    template<bool is_pod>
    static typename std::enable_if<!is_pod,CByteArray>::type serialize_t(const T& value)
    { return Serializer<HLVariant>::serialize(HLVariant(value)); }

    static CByteArray serialize(const T& value)
    { return serialize_t<std::is_pod<T>::value>(value); }
};

template<>
struct Serializer<HLVariant>
{
    static CByteArray serialize(const HLVariant&)
    { return CByteArray(); }
};

或者,您可以直接在类模板的范围内应用SFINAE:

template<typename T,typename = void> struct Serializer;

template<>
struct Serializer<HLVariant>
{
    static CByteArray serialize(const HLVariant&)
    { return CByteArray(); }
};

template<typename T>
struct Serializer<T,typename std::enable_if<is_pod<T>::type>
{
    static CByteArray serialize(const T&)
    { return CByteArray(); }
};

template<typename T>
struct Serializer<T,typename std::enable_if<!is_pod<T>::type>
{
    static CByteArray serialize(const T&value)
    { return Serializer<HLVariant>::serialize(HLVariant(value));
};

或者你可以摆脱类Serializer并通过模板函数直接声明:

inline CByteArray
serialize(const HLVariant&)
{ return CByteArray(); }

template<typename T>
inline typename enable_if<std::is_pod<T>::value,CByteArray>::type
serialize(const T&)
{ return CByteArray(); }

template<typename T>
inline typename enable_if<!std::is_pod<T>::value,CByteArray>::type
serialize(const T&value)
{ return serialize(HLVariant(value)); }

BTW,C 14定义了非常有用的别名

template<bool C,typename T>
using enable_if_t = typename enable_if<C,T>::type;

但是你当然可以这样做.这样可以一直避免繁琐的typename和:: type.

猜你在找的C&C++相关文章