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

发布于 2025-01-10 22:08:02 字数 2091 浏览 0 评论 0原文

我希望下面的 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";
}

I expected the 2 definitions below to co-exist because i am adding a type checking code but it gives error as already declared. Why so and what needs to be changed?

#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);
}

Errors as below

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:

Even this syntax without default arguments doesn't work

#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";
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无法回应 2025-01-17 22:08:02

为什么会这样以及需要改变什么?

来自 std::enable_if 的文档

一个常见的错误是声明两个仅在默认模板参数上不同的函数模板。这不起作用因为声明被视为同一函数模板的重新声明(函数模板等效性中不考虑默认模板参数

在给定示例中解决此问题的一种方法是在指定函数模板的返回类型时使用 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;
}

演示

解决方案 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);
}

演示

Why so and what needs to be changed?

From 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).

One way to solve this problem in your given example would be to use the enable_if_t expression when specifying the return type of the function template instead of as a default argument, as shown below:

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

Solution 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文