Reputation: 13
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
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