Let's remove some code.
template<
class T,
class U/* = std::enable_if_t<std::is_same<int, T>::value>*/
>
void g() { }
template<
class T,
class U/* = std::enable_if_t<std::is_same<double, T>::value>*/
>
void g() { }
would you be surprised if the compiler rejected the two above templates?
They are both template functions of "type" template<class,class>void()
. The fact that the 2nd type argument has a different default value matters not. That would be like expecting two different print(string, int)
functions with different default int
values to overload. ;)
In the first case we have:
template<
typename T,
typename std::enable_if<std::is_same<int, T>::value>::type* = nullptr
>
void f() { }
template<
typename T,
typename std::enable_if<std::is_same<double, T>::value>::type* = nullptr
>
void f() { }
here we cannot remove the enable_if
clause. Updating to enable_if_t
:
template<
class T,
std::enable_if_t<std::is_same<int, T>::value, int>* = nullptr
>
void f() { }
template<
class T,
std::enable_if_t<std::is_same<double, T>::value, int>* = nullptr
>
void f() { }
I also replaced a use of typename
with class
. I suspect your confusion was because typename
has two meanings -- one as a marker for a kind of template
argument, and another as a disambiguator for a dependent type.
Here the 2nd argument is a pointer, whose type is dependent on the first. The compiler cannot determine if these two conflict without first substituting in the type T
-- and you'll note that they will never actually conflict.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…