【问题标题】:How to create a template function that accepts a vector of values, with the vector type specified?如何创建一个接受值向量的模板函数,并指定向量类型?
【发布时间】: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 的向量与尝试读取单个intread&lt;int&gt;() 具有相同的签名。

为了解决这个问题,我想让矢量签名看起来像这样:read&lt;std::vector&lt;int&gt;&gt;(),但我不知道该怎么做。有没有办法在模板参数中要求向量类型,但仍然获得它在函数中使用的内部类型?

谢谢!!

【问题讨论】:

  • 标签调度(或类专业化)允许拥有“更多”控制(更简单的重载):template &lt;typename T&gt; struct Tag{}; template &lt;typename T /*, ..*/&gt; T read_impl(Tag&lt;T&gt;); template &lt;typename T /*, ..*/&gt; std::vector&lt;T&gt; read_impl(Tag&lt;std::vector&lt;T&gt;&gt;); /*..*/ template &lt;typename T&gt; T read() { return read_impl(Tag&lt;T&gt;{}); }

标签: c++ templates vector


【解决方案1】:

是的,你可以假设std::vector作为模板参数,并从std::vector::value_type获取元素类型。例如

template<typename V, std::enable_if_t<std::is_integral<typename V::value_type>::value, bool> = true>
//                                                     ^^^^^^^^^^^^^^^^^^^^^^ check the element type
inline V read() {
    using T = typename V::value_type; // get the element type
    ...
}

那你可以叫它read&lt;std::vector&lt;int&gt;&gt;()

顺便说一句:这不仅适用于std::vector,还适用于其他具有嵌套类型value_type(整数类型)的容器。

【讨论】:

  • 非常感谢,这就是我所缺少的!!
猜你喜欢
  • 2021-03-23
  • 2023-02-26
  • 1970-01-01
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-03
  • 1970-01-01
相关资源
最近更新 更多