I'm looking for a possibility for using a function where I pass a pointer to uint16_t or uint32_t values.
Currently I use the two overloaded functions
std::vector<float> calcMap(uint16_t* map)
std::vector<float> calcMap(uint32_t* map)
Since they return float values the calculation is the same for 16 and 32 bit values. The only difference is the data type which is needed to go through the array pointed to. I don't want to have the whole content of the function twice, is there a possibility to make it type independent?
Mostly for completeness:
In case you don't want to expose the implementation of the functions, and for whatever reason don't want to forward to a private template. There's the oft overlooked option of explicit template instantiation declarations. It's rather easy:
Declare a template, and explicitly declare the instantiations of it in a header:
template<typename T> std::vector<float> calcMap(T*);
extern template std::vector<float> calcMap<>(uint16_t*);
extern template std::vector<float> calcMap<>(uint32_t*);
In your own original translation unit, define one template, and add two explicit instantiations:
template<typename T>
std::vector<float> calcMap(T*) {
// Now we implement
}
template std::vector<float> calcMap<>(uint16_t*); // Now this will link
template std::vector<float> calcMap<>(uint32_t*); // As will this
How is it different from drescherjm's excellent suggestion? It will produce less symbols. And in case your compiler isn't too good at link time inlining, it won't require it to skip the forwarding functions.
If you only want to accept uint16_t
and uint32_t
, then something along the following lines should work:
template <class T,
class = typename std::enable_if<
std::is_same<typename std::decay<T>::type, uint16_t>::value ||
std::is_same<typename std::decay<T>::type, uint32_t>::value>::type>
std::vector<float> calcMap(T * map) {
// Code
}
You have to #include <type_traits>
and enable at least C++11 for the above to work.
By the way, if your code only reads the data, then changing T *
into T const *
might be a good idea. Or hell, T const * const
while you're at it.
You might also be interested in std::is_integral
, in case you just want to allow more than the 2 types used above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With