如果您编写一个函数,它们都可以正常工作。
但是当你想要两个替代功能时,这样
template <typename T, typename = std::enable_if_t<true == std::is_integral_v<T>>>
void foo (T const &)
{ std::cout << "is integral" << std::endl; }
template <typename T, typename = std::enable_if_t<false == std::is_integral_v<T>>>
void foo (T const &)
{ std::cout << "isn\'t integral" << std::endl; }
在这种情况下会出现编译错误
template <typename T, std::enable_if_t<true == std::is_integral_v<T>, int> = 0>
void foo (T const &)
{ std::cout << "is integral" << std::endl; }
template <typename T, std::enable_if_t<false == std::is_integral_v<T>, int> = 0>
void foo (T const &)
{ std::cout << "isn\'t integral" << std::endl; }
有效。
原因?
考虑一下你在玩 SFINAE,即 Substitution Failure Is Not An Error。
重点是替换。
第一种方式,当你调用时
foo(0)
替换带来
template <typename T, typename = void>
void foo (T const &)
{ std::cout << "is integral" << std::endl; }
template <typename T, typename>
void foo (T const &)
{ std::cout << "isn\'t integral" << std::endl; }
也就是说...您有两个具有相同签名的函数(默认模板参数不会更改函数的签名)和调用它的冲突。
第二种方式你只有
template <typename T, int = 0>
void foo (T const &)
{ std::cout << "is integral" << std::endl; }
因为第二个函数中的替换失败使该函数无法使用并被丢弃。所以你只有一个可用的函数,没有碰撞。