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 */ }
