I need a function void foo(T &t)
that will have one implementation for char*
, another for std::is_integral_v
and yet another for std::is_floating_point
types.
I don't want to make a constexpr approach because it would create a gigantic function with a lot of branches that are difficult to navigate and understand and scale.
I've tried SFINAE but i can't fully understand how it works
The code i've written before
template<typename T>
void foo(T *t);
template<>
void foo<char *>(char **t) { /* does some logic */ }
template<>
void foo<int>(int *t) { /* does some logic */ }
template<>
void foo<float>(float *t) { /* does some logic */ }
i want to make an int
specialization to also accept all int#_t
, uint#_t
and other integral types
the same i want for my float
also accept double
types without copy-pasting implementation with different cast i need a single scalable solution with SFINAE or any other technology
CodePudding user response:
This does the job:
// For integral types only:
template<typename T>
std::enable_if_t<std::is_integral_v<T>> foo(T *t)
{
cout << "integer" << endl;
}
// For floating point types only:
template<typename T>
std::enable_if_t<std::is_floating_point_v<T>> foo(T *t)
{
cout << "floating point" << endl;
}
template <typename T>
std::enable_if_t<std::is_pointer_v<T>> foo(T *t)
{
cout << "pointer" << endl;
}
int main()
{
long a;
double b;
foo(&a);
foo(&b);
const char *c = "test";
foo(&c);
return 0;
}
https://godbolt.org/z/b5fT9PGbv
CodePudding user response:
Use enable_if
:
#include<type_traits>
void foo(char* t) { /* does some logic */ }
template<typename T, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
void foo(T* t) { /* does some logic */ }
template<typename T, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
void foo(T* t) { /* does some logic */ }