假设我想通过以下方式序列化以下数据。有些数据是 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 类型。