为什么具有相同名称和参数类型检查的函数不能共存?

Why can't functions with same name and argument type check can't co-exist?

我希望下面的 2 个定义共存,因为我正在添加一个类型检查代码,但它给出了已经声明的错误。为什么会这样,需要更改什么?

#include <iostream>
#include <type_traits>

template<class T, class = std::enable_if_t<std::is_integral_v<T>>>
bool is_even(T value)
{
    return ((value % 2) == 0);
}

template<class T, class = std::enable_if_t<std::is_floating_point_v<T>>>
bool is_even(T value)
{
    std::cout << "\n Floating point version ";
    return false;
}
    
int main()
{
    std::cout << "is_even (4) = " << std::boolalpha << is_even(4);
    std::cout << "is_even (4.4) = " << std::boolalpha << is_even(4.4);
}

错误如下

Error(s):
462942513/source.cpp:13:6: error: redefinition of ‘template<class T, class> bool is_even(T)’
 bool is_even(T value)
      ^~~~~~~
462942513/source.cpp:7:6: note: ‘template<class T, class> bool is_even(T)’ previously declared here
 bool is_even(T value)
      ^~~~~~~
462942513/source.cpp: In function ‘int main()’:
462942513/source.cpp:22:69: error: no matching function for call to ‘is_even(double)’
     std::cout << "is_even (4.4) = " << std::boolalpha << is_even(4.4);
                                                                     ^
462942513/source.cpp:7:6: note: candidate: template<class T, class> bool is_even(T)
 bool is_even(T value)
      ^~~~~~~
462942513/source.cpp:7:6: note:   template argument deduction/substitution failed:

即使这种没有默认参数的语法也不起作用

#include <iostream>
#include <type_traits>

template<class T, std::enable_if_t<std::is_integral_v<T>>>
bool is_even(T value)
{
    return ((value % 2) == 0);
}

template<class T, std::enable_if_t<std::is_floating_point_v<T>>>
bool is_even(T value)
{
    return false;
}

int main()
{
   
    std::cout << "is_even (4) = " << std::boolalpha << is_even(4) << "\n";
    std::cout << "is_even (4.4) = " << std::boolalpha << is_even(4.4) << "\n";
}

Why so and what needs to be changed?

来自std::enable_if 's documentation

A common mistake is to declare two function templates that differ only in their default template arguments. This does not work because the declarations are treated as redeclarations of the same function template (default template arguments are not accounted for in function template equivalence).

在给定示例中解决此问题的一种方法是在指定函数模板的 return 类型时使用 enable_if_t 表达式而不是默认参数,如下所示:

template<class T>
std::enable_if_t<std::is_integral_v<T>,bool> is_even(T value)
{
    return ((value % 2) == 0);
}

template<class T>
std::enable_if_t<std::is_floating_point_v<T>, bool> is_even(T value)
{
    std::cout << "\n Floating point version ";
    return false;
}

Demo

解决方案 2

#include <iostream>
#include <type_traits>

template<class T, std::enable_if_t<std::is_integral_v<T>, bool> = true>
auto is_even(T value)
{
    return ((value % 2) == 0);
}

template<class T, std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
auto is_even(T value)
{
    std::cout << "\n Floating point version ";
    return false;
}
    
int main()
{
    std::cout << "is_even (4) = " << std::boolalpha << is_even(4);
    std::cout << "is_even (4.4) = " << std::boolalpha << is_even(4.4);
}

Demo