Template argument deduction doesn't work on *dependent* types, like the
...::type for your formal argument.
From the compiler's point of view there could be any number of
specializations of `enable_if`, with `::type`s that didn't at all
resemble the `T` type. And these specialization could be defined in
indirect ways that involved much compile time activity to straighten
out. It would be unreasonable to require it to do that /in general/.
Template argument deduction is instead a more or less direct matching,
not considering any type indirection.
So, to do what you're trying to do, do
template<
class T,
class = enable_if_t< is_unsigned_v< T > >
>
void f123( const T value ) ...
Due to historical reasons, that template aliases were not available at
the time the `enable_if` appeared, the notation is full of annoying
ticks and warts like `_t` and `_v`.
I tend to reduce them via ¹simple aliases, e.g., off the cuff
template< bool condition > using Enable_if_ =
std::enable_if_t<condition>;
In some cases, such as `is_const_` and `is_base_and_derived_`, the
wrapper or alias also adds much needed generality or clarity.
Cheers!
- Alf
References:
¹ E.g. see <url:
https://github.com/alf-p-steinbach/cppx-core/blob/master/source/cppx-core/language/tmp/basic-type-traits.hpp>