[英]Simultaneously existing a template function with std::enable_if and an ordinary template function
我有一个简单的功能:
template<class T>
typename std::enable_if_t<std::is_arithmetic_v<T>>
foo(T val) { }
我还想有另一个同名的函数:
template<class T>
void foo(T value) { }
我想用算术类型调用第一个函数,为所有其他类型调用第二个函数。 我的一个想法是将第二个函数更改为:
template<class T>
typename std::enable_if_t<!std::is_arithmetic_v<T>>
foo(T val) { }
但有没有更好的方法来实现这一目标?
更好、更直观的方法是使用 C++20 概念。
#include <concepts>
template<class T>
requires std::is_arithmetic_v<T>
void foo(T value) { }
template<class T>
void foo(T value) { }
当您调用foo(0)
,由于满足第一个重载的约束,它将优先于第二个无约束重载。
调用foo("hello")
,由于不满足第一个重载的约束,编译器会选择第二个重载。
您可以通过利用重载解析来做到这一点:
template<class T>
typename std::enable_if_t<std::is_arithmetic_v<T>>
foo(T val, int)
{
std::cout << "arithmetic: " << (val + val) << '\n';
}
template<typename T>
void foo(const T& val, long)
{
std::cout << "Def: " << val << '\n';
}
template<typename T>
void foo(T&& x)
{
foo(std::forward<T>(x), 0);
}
https://godbolt.org/z/sM1KbT8vE
现在int
重载是首选,但如果它因为 SFINAE 而失败,它会跳转到long
重载。
在简单的情况下,我更喜欢!std::eneble_if_t
方法,但如果您有更多特殊情况,重载解析会更方便。
使用if constexpr
:
template<class T>
void foo(T value)
{
if constexpr (std::is_arithmetic_v<T>) {
// ... one implementation
} else {
// ... another implementation
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.