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

问题描述 投票:3回答:3

当我有一个带有成员函数的结构,我专注于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";
  }
};

提前致谢!

c++ c++11
3个回答
4
投票

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

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

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


1
投票

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

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 in C ++ 17,在C ++ 11/14中使用或者static_if或SFINAE或traits类构造。

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


0
投票

我认为匿名默认模板参数是一个更好的解决方案,因为您不必复制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";
}

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

© www.soinside.com 2019 - 2024. All rights reserved.