繁体   English   中英

同时存在一个带有 std::enable_if 的模板函数和一个普通的模板函数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM