I know how to do it with any data type with template:
template<typename T>
T myFunc(T data) { ... }
But is there a way to narrow the set of allowed types to for example int
and char
or std::string
and std::wstring
, so the compiler would throw an error when encountering not allowed argument type and I will get error on compile time instead of run time ?
edit: Big thanks to ecatmur, now I understand the whole concept.
template<typename itemA_type, typename itemB_type>
typename std::enable_if<
(
std::is_same<itemA_type, int>::value ||
std::is_same<itemA_type, char>::value) &&
(
std::is_same<itemB_type, std::string>::value ||
std::is_same<itemB_type, std::wstring>::value ||
std::is_same<itemB_type, const char*>::value ||
std::is_same<itemB_type, const wchar_t*>::value
) ,
void
>::type
myFunction(itemA_type itemA, itemB_type itemB) {
using namespace std;
cout << itemA << itemB << endl;
}
Take this utility trait class:
template<typename T, typename U, typename... Us>
struct is_any_of
: std::integral_constant<
bool,
std::conditional<
std::is_same<T,U>::value,
std::true_type,
is_any_of<T,Us...>
>::type::value
>
{ };
template<typename T, typename U>
struct is_any_of<T,U> : std::is_same<T,U>::type { };
Then you can use it in a static assertion:
template<typename T>
T myFunc(T data)
{
static_assert( is_any_of<T, int, char, std::string>{}, "T not allowed");
}
You can use std::is_convertible
or std::is_constructible
instead of std::is_same
if you feel it's more appropriate.
Live example.
A simple solution using enable_if
and is_same
:
template<typename T>
typename std::enable_if<
std::is_same<T, int>::value ||
std::is_same<T, char>::value,
T>::type
myFunc(T data) { ... }
As the predicate on T
becomes more complex (for example, do you just allow string
and wstring
, or other specializations of basic_string
?) you may start to want to write more complex predicate metafunctions; but for now, a simple expression is likely to suffice.
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