In a specific requirement I need to allow instantiation of a template function func
only for a specific set of allowed types.
Therefore I tried to use already available std::type_traits
and then used std::enable_if
to block instantiation. Here is my implementation.
// C++17
#include <vector>
#include <cstdint>
#include <iostream>
#include <type_traits>
using my_int_t = std::int16_t; // T1
using my_string_t = std::string; // T2
using my_vec_t = std::vector<int>; // T3
// and so on .. a long list of types
/* Check input Type T : if it belongs to {T1,T2,T3}
If it belongs then only allow this version of func to instantiate
*/
template<typename T, typename T1,typename T2,typename T3>
using isCompatible = std::bool_constant<std::is_same_v<T,T1>
|| std::is_same_v<T,T2>
|| std::is_same_v<T,T3> >;
template<typename T>
using CompatibleTypeCheck = std::enable_if_t< isCompatible<std::remove_reference_t<T>,
my_int_t,
my_string_t,
my_vec_t>::value >;
template<typename T,
typename = CompatibleTypeCheck<T>>
void func(T&& val) {
std::cout <<"Hello from Generic Func" << std::endl;
}
int main() {
// int z = 10;
// func(z); // Error ! as expected
my_int_t w = 100;
func(w); // OK
}
But the problem is there are too many allowed types. Is there is better way to clean both of the alias templates ? i.e. isCompatible
and CompatibleTypeCheck
.
If there is any better "idiomatic" way to achieve the same result, please suggest it.
You can write isCompatible
like this:
template<typename T, typename ...Ts>
using isCompatible = std::bool_constant<(std::is_same_v<T,Ts> || ...)>;
There's not much you can do for CompatibleTypeCheck
since you need to specify all the allowed types somewhere.
Here's a demo.
Note that enable_if
is usually used when you want to enable or disable particular overloads. In your case, the easier way would be to just static_assert
inside the function definition:
template<typename T>
void func(T&& val) {
static_assert(isCompatible<std::remove_reference_t<T>,
my_int_t,
my_string_t,
my_vec_t>::value);
std::cout <<"Hello from Generic Func" << std::endl;
}
which avoids the need for CompatibleTypeCheck
entirely.
Here's a demo.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments