Reputation: 778
I have a template function that does something depending on the type passed as a template argument:
template<class T>
void foo() {
if constexpr (std::is_integral_v<T>) {
// ...
} else if constexpr ... {
// ...
}
}
The problem with this it that I don't really need to have a function instantiation for every possible integral type (to avoid template code bloat), so I would like to have only one instance that takes a int
and if we pass the type char
or short
it calls the int
version. I would like something like this:
template<class T>
void foo() {
if constexpr (std::is_same_v<T, int>) { // Only check for `int`, because "lower" types will be converted to int
// ...
} else if constexpr ... {
// ...
}
}
foo<short>(); // Call `foo<int>`
foo<char>(); // Call `foo<int>`
foo<int>(); // Call `foo<int>`
Maybe I can wrap the function inside a struct and have a struct<char>
that extends the struct<int>
?
Note that there is no "values" anywhere, I just have template parameters.
Upvotes: 0
Views: 80
Reputation: 42776
You can turn foo
into a callable object, and use using
alias to select different instantiations according to T
, for example:
#include <type_traits>
template<class T>
struct foo {
void operator()() {
if constexpr (std::is_same_v<T, int>) {
// ...
} else if constexpr ... {
// ...
}
}
};
template<class T>
auto bar = std::conditional_t<std::is_integral_v<T>, foo<int>, foo<T>>();
int main() {
bar<short>(); // Call `foo<int>`
bar<char>(); // Call `foo<int>`
bar<int>(); // Call `foo<int>`
bar<const char*>(); // Call `foo<const char*>`
}
Upvotes: 2