3

假设我想通过以下方式序列化以下数据。有些数据是 memcopy 可序列化的,有些则不是。

    MemCpySerializable ser;
    NonMemCpySerializable nonser;

    const std::vector<MemCpySerializable> vec1;
    const std::vector<NonMemCpySerializable> vec2;

    FastBinarySerializer<MemCpySerializable>::SerializeValue(ser);
    FastBinarySerializer<NonMemCpySerializable>::SerializeValue(nonser);
      
    FastBinarySerializer<std::vector<MemCpySerializable>>::SerializeValue(vec1);
    FastBinarySerializer<std::vector<NonMemCpySerializable>>::SerializeValue(vec2);

前面提到的类型是这样定义的:

template<typename T>
struct IsMemcopySerializable
{
    static constexpr bool value = std::is_trivially_copyable<T>::value && std::is_trivially_destructible<T>::value &&
        !std::is_pointer<T>::value;
};

struct MemCpySerializable
{
};

template<>
struct IsMemcopySerializable<MemCpySerializable>
{
    static constexpr bool value = true;
};


struct NonMemCpySerializable
{
};

template<>
struct IsMemcopySerializable<NonMemCpySerializable>
{
    static constexpr bool value = false;
};

如您所见,这两种结构类型的唯一区别是 IsMemcopySerializable::value 中的值。

请注意,对于所有 T,IsMemcopySerializablestd::vector<T>::value 为 false。

我们通过以下方式定义 FastBinarySerializer:

//Default Template Arguments
struct DefaultType;
struct NonDefaultType; //This is unused, but it may be helpful as a default template argument.

//Primary Template
template<typename T, typename U = DefaultType, typename Enable = void >
struct FastBinarySerializer;

template<typename T, typename U>
struct FastBinarySerializer<
    T,
    U,
    typename std::enable_if<
    IsMemcopySerializable<T>::value>::type>
{
    static void SerializeValue(const T& value) noexcept
    {
        //Memcopy serialization
    }
};

template<typename T, typename U>
struct FastBinarySerializer<
    T,
    U,
    typename std::enable_if<
    !IsMemcopySerializable<T>::value>::type>
{
    static void SerializeValue(const T& value)
    {
        //Fallback case. This will only work for specific types (not std::vector<T>). 
        // We will assume that any nonspecialized type T with !IsMemcopySerializable<T>::value
        // will be handled by this function.
    }

};

template<typename T>
struct FastBinarySerializer<std::vector<T>, DefaultType, void>
{
    static void SerializeValue(const std::vector<T>& value)
    {
        FastBinarySerializer<uint32_t>::SerializeValue(value.size());

        for (auto& item : value)
        {
            FastBinarySerializer<T>::SerializeValue(item);
        }
    }
};

问题是以下行会生成此错误:

    FastBinarySerializer<std::vector<MemCpySerializable>>::SerializeValue(vec1);
      //error C2752: 'FastBinarySerializer<std::vector<MemCpySerializable, 
      //std::allocator<MemCpySerializable>>,DefaultType,void>': more than one partial specialization 
      //matches the template argument list

问题是 std::vector 不是 MemcopySerializable。FastBinarySerializer 类模板匹配两个特化。有没有办法让 FastBinarySerializerstd::vector<NonMemCpySerializable> 仅与 std::vector 专业化匹配?我尝试使用 DefaultType 和 NonDefaultType 来强制 std::vector 专业化被优先考虑无济于事。

我的约束:FastBinarySerializer 必须保留为类模板,而不是函数模板。SerializeValue 必须始终具有相同的函数签名。我无法在类模板实例化中手动指定 DefaultType 或 NonDefault 类型。

4

0 回答 0