【发布时间】:2021-09-05 14:55:21
【问题描述】:
奇怪的问题,但让我解释一下。我正在创建一个反序列化器,它需要具有用于反序列化不同类型(包括基元、数组和向量)的专用函数。一个例子是积分函数,它看起来像这样:
/** Reads an integral. */
template<typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
inline T read() {
ind += sizeof(T);
return reinterpret_cast<T>(data[ind - sizeof(T)]);
}
当我尝试添加矢量支持时,我遇到了问题。理想情况下,我想为包含整数类型的向量编写一个特化,我最初认为我可以这样做:
/** Reads a vector of integrals. */
template<typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
inline std::vector<T> read() {
usize len = read<size_t>();
auto startInd = ind;
ind += len * sizeof(T);
return std::vector<T>(
reinterpret_cast<const T*>(&data[startInd]),
reinterpret_cast<const T*>(&data[ind]));
}
但随后会出现一个问题,即尝试读取int 的向量与尝试读取单个int、read<int>() 具有相同的签名。
为了解决这个问题,我想让矢量签名看起来像这样:read<std::vector<int>>(),但我不知道该怎么做。有没有办法在模板参数中要求向量类型,但仍然获得它在函数中使用的内部类型?
谢谢!!
【问题讨论】:
-
标签调度(或类专业化)允许拥有“更多”控制(更简单的重载):
template <typename T> struct Tag{}; template <typename T /*, ..*/> T read_impl(Tag<T>); template <typename T /*, ..*/> std::vector<T> read_impl(Tag<std::vector<T>>); /*..*/ template <typename T> T read() { return read_impl(Tag<T>{}); }。