I have three functions that do almost the same thing, but the process is a little bit different according to the parameters type:
template<typename T> void Func1(const T *in, T *out)
{
static_assert(std::is_same<T, INT8>::value
|| std::is_same<T, UINT8>::value
|| std::is_same<T, INT16>::value
|| std::is_same<T, UINT16>::value, "");
//...
}
template<typename T> void Func2(const T *in, T *out)
{
static_assert(std::is_same<T, INT32>::value || std::is_same<T, UINT32>::value, "");
//...
}
template<typename T> void Func3(const T *in, T *out)
{
static_assert(std::is_same<T, float>::value || std::is_same<T, double>::value, "");
//...
}
But I don't want the user to have to decide which function call, so I try to do it automatically. Unfortunately so far (I am a C++ beginner), the only way I know would be:
template<typename T> void Function(const T *in, T *out)
{
if (std::is_same<T, UINT8>::value
|| std::is_same<T, UINT16>::value
|| std::is_same<T, INT8>::value
|| std::is_same<T, INT16>::value)
{
Func1(in, out);
return ;
}
if ( std::is_same<T,INT32>::value || std::is_same<T,UINT32>::value )
{
Func2(in, out);
return ;
}
if ( std::is_same<T,float>::value || std::is_same<T,float>:: double )
{
Func3(in, out);
return ;
}
}
I find this solution completely ugly, and I would like to know if something better/faster/more elegant is possible?
If you use C++11 or greater, you can use type_traits (SFINAE) :
template<typename T>
typename std::enable_if<std::is_same<T, INT8>::value
|| std::is_same<T, UINT8>::value
|| std::is_same<T, INT16>::value
|| std::is_same<T, UINT16>::value>::type Function(const T*in, T*out)
{
Func1(in, out);
}
template<typename T>
typename std::enable_if<std::is_same<T, INT32>::value
|| std::is_same<T, UINT32>::value >::type Function(const T*in, T*out)
{
Func2(in, out);
}
template<typename T>
typename std::enable_if<std::is_same<T, float>::value
|| std::is_same<T, double>::value >::type Function(const T*in, T*out)
{
Func3(in, out);
}
Example: http://coliru.stacked-crooked.com/a/b4f000fa6ffa8f19
Or if you can't use C++11 or greater, you can use overload instead of template:
void Function(const UINT8 *int, UINT8 * out)
{
Func1(in, out);
}
...
void Function(const UINT32 *int, UINT32 * out)
{
Func2(in, out);
}
...
Or you can use template specialization but, in this case, it's not really relevant (I leave it here, because it was in original answer):
template<typename T> Function(const T *in, T *out);
template<> void Function(const UINT8 *in, UINT8 * out)
{
Func1(in, out);
}
template<> void Function(const INT8 *in, INT8 * out)
{
Func1(in, out);
}
....
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