如何使用 std::enable_if 时拆分声明和实现

Howto split declaration and implementation when using std::enable_if

本文关键字:声明 拆分 实现 何使用 std enable if      更新时间:2023-10-16

当我有一个带有我专门研究的成员函数的结构时std::enable_if如何从实现中拆分声明?

示例代码(在 ideone 中)

struct node
{
  template < class T >
  void analyze(T t, typename std::enable_if<std::is_integral<T>::value>::type* = 0)
  {
    std::cout << "is_arithmetic type " << t << "n";
  }
  template < class T >
  void analyze(T t, typename std::enable_if<std::is_floating_point<T>::value>::type* = 0)
  {
    std::cout << "is_floating_point type " << t << "n";
  }
  void analyze(bool t)
  {
    std::cout << "is bool type " << t << "n";
  }
};

提前感谢!

就像任何模板化方法一样:

struct node {
  template <class T>
  void analyze(T t, typename std::enable_if<std::is_integral<T>::value>::type* = 0);
};
template <class T>
void node::analyze(T t, typename std::enable_if<std::is_integral<T>::value>::type*) {
    std::cout << "is_arithmetic type " << t << "n";
}

请注意,此处没有模板专用化(不能对成员函数进行部分专用化),并且具有不同的重载。

我会编写不同的帮助程序函数和标记调度。

template < class T >
void analyze(T t, int_tag);
template < class T >
void analyze(T t, float_tag );
void analyze(bool t, bool_tag );
template<class T>
auto get_tag();
void analyze( T t ){ return analyze(t, get_tag<T>());

现在我们通过标签调度将重载路由(get_tag)与重载分开。

如何定义标签(std::integral_constantstruct int_tagtag<int>或其他)取决于你;它们必须是相互不兼容和空的。

如何写get_tag也取决于你; if constexpr在 C++17 中,使用 或 static_if 或 SFINAE 或 C++11/14 中的性状类构造。

我认为get_tag的定义是analyze而不是实现接口的一部分;如果我们直接分离重载解决规则,则不要使用 enable,公开它,然后将业务逻辑的实现放在其他地方。

我认为匿名默认模板参数是更好的解决方案,因为您不必将enable_if条件复制两次。

struct node
{
    template <class T, typename = std::enable_if_t<std::is_integral_v<T>>>
    void analyze( T t );
};
template <class T, typename>
void node::analyze( T t )
{
    std::cout << "is_arithmetic type " << t << "n";
}

我知道它不适合具体的例子,因为它确实回答了这个问题。