Auri
Auri

Reputation: 13

How to create a template function that accepts a vector of values, with the vector type specified?

Weird question but let me explain. I'm creating a Deserializer that needs to have specialized functions for Deserializing different types, including primitives, arrays, and vectors. An example of this is the integral function, which looks like this:

    /** 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)]);
    }

When I tried to add vector support, I ran into a problem. Ideally, I'd like to write a specialization for vectors containing integral types, and I initially thought I could do it like this:

    /** 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]));
    }

but then a problem occurs where trying to read a vector of int has the same signature as trying to read a single int, read<int>().

To fix this, I want to make it so that the vector signature looks like this: read<std::vector<int>>(), but I can't figure out how to do this. Is there a way to require the vector type in the template argument, but still get the inner type it uses for use in the function?

Thanks!!

Upvotes: 1

Views: 784

Answers (1)

songyuanyao
songyuanyao

Reputation: 172894

Yes, you can suppose std::vector as the template parameter, and get the element type from std::vector::value_type. E.g.

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
    ...
}

Then you can call it as read<std::vector<int>>().

BTW: This doesn't only work for std::vector, but also other containers having nested type value_type which is integral type.

Upvotes: 1

Related Questions