Here is what I want:
struct type1{};
template <typename T, std::enable_if_t<std::is_xxx_v<T, type1>,void>* = nullptr>
void my_function(const T& obj)
{
std::cout << "operation on type1" << std::endl;
}
template <typename T, std::enable_if_t<!std::is_xxx_v<T, type1>,void>* = nullptr>
void my_function(const T& obj)
{
std::cout << "operation on other types" << std::endl;
}
after days, i have to add another type
struct type2{};
But how can I implement my_function
for type1
, type2
and other types?
I can write it like this:
struct type2{};
template <typename T, std::enable_if_t<std::is_xxx_v<T, type1>,void>* = nullptr>
void my_function(const T& obj)
{
std::cout << "operation on type1" << std::endl;
}
template <typename T, std::enable_if_t<std::is_xxx_v<T, type2>,void>* = nullptr>
void my_function(const T& obj)
{
std::cout << "operation on type2" << std::endl;
}
// my_function for other types
template <typename T, std::enable_if_t<!std::is_xxx_v<T, type1> && !std::is_xxx_v<T, type2>,void>* = nullptr>
void my_function(const T& obj)
{
std::cout << "operation on other types" << std::endl;
}
but this is not a good method, since one day, i add struct type3{};
, i have to add a new func for type3
(i can accept this), but i also have to change code for other types which i don't want to.
what i want is if i add a new type3
, is that possible that i only add a new overloaded function for type3
, and the code for other types has no need to change.
Depending on the std::is_xxx_v
you use, you might be able to use template specialization. First declare the default function working with any type of argument:
template<typename T>
void my_function_specialization(const T& obj) {
std::cout << "operation on other types" << std::endl;
}
And then you can specialize the function on the types you want
template<>
void my_function_specialization(const type1& obj) {
std::cout << "operation on type1" << std::endl;
}
template<>
void my_function_specialization(const type2& obj) {
std::cout << "operation on type2" << std::endl;
}
/*
and so on...
*/
Otherwise you can use if constexpr
to distingush between different cases:
template<typename T>
void my_function_if_constexpr(const T& obj) {
if constexpr (std::is_xxx_v<type1, T>) {
std::cout << "operation on type1" << std::endl;
} else if constexpr (std::is_xxx_v<type2, T>) {
std::cout << "operation on type2" << std::endl;
} else if constexpr (/* and so on... */) {
/* ... */
} else {
std::cout << "operation on other types" << std::endl;
}
}