When you try to use these function templates, there can be ambiguity issues. If you call foo with an arithmetic type, both template overloads will be considered valid, and the compiler won't know which one to choose.
You can use specialization or tag dispatching to properly handle different cases.
std::cout << "Called when T is not arithmetic" <<std::endl;
foo_impl<T>()(t);
}
int main() {
@ -31,6 +40,6 @@ int main() {
}
```
In this example, we define two `foo` function template specializations. The first one is enabled when `T` is an arithmetic type, while the second one is enabled when `T` is not an arithmetic type. The `std::enable_if_t` inside the template parameter list allows us to control which specialization is valid for a given type of `T`.
In this example, we define two `foo_impl` functions are specialized based on the boolean value of `std::is_arithmetic<T>`. The first one is enabled when `T` is an arithmetic type, while the second one is enabled when `T` is not an arithmetic type. The `foo` function then calls the appropriate `foo_impl` specialization based on the result of the type trait.
When calling `foo(a)` with an integer, the first specialization is selected, and when calling `foo(s)` with a string, the second specialization is selected. If there is no valid specialization, the code would fail to compile.
When calling `foo(a)` with an integer, the first specialization is selected, and when calling `foo(s)` with a string, the second specialization is selected. If there is no valid specialization, the code would fail to compile.