Although this is somewhat deprecated by the introduction of concepts in newer versions of C++, if you're stuck on an older version, this should do the job for free template funtions:
template<typename Type_T>
constexpr int MyFunction() = delete; //The function
template<>
constexpr int MyFunction<bool>() //A specialisation for bool
{
return 1;
}
//The type traits
namespace Internal
{
template<typename Type_T, typename = void>
struct IsMyFunctionImplemented : std::false_type
{ };
template<typename Type_T>
struct IsMyFunctionImplemented<Type_T
, std::void_t<decltype(MyFunction<Type_T>())>
> : std::true_type
{ };
}
template<typename Type_T>
inline constexpr bool IsMyFunctionImplemented_v = Internal::IsMyFunctionImplemented<Type_T>::value;
Usage:
IsMyFunctionImplemented_v<bool>; //returns true
IsMyFunctionImplemented_v<float>; //returns false
Working example here:
https://godbolt.org/z/qGn5WGGrc
Note that the default implementation for the function template has to be declared as deleted, otherwise this will not work!
This is because any call towards MyFunction<Type_T>()
is allowed if there is a default implementation, and thus the expression std::void_t<decltype(MyFunction<Type_T>())>
does not equate to void
because decltype(MyFunction<Type_T>())
provides a valid function signature.
Also note that this only validates the function name and arguments, not its return type, if this is important to you, you'll need to make some modifications, here's a great example for member functions:
Check if a class has a member function of a given signature