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

时间:2017-01-12 13:15:44

标签: c++ c++11

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

提前致谢!

3 个答案:

答案 0 :(得分: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 :(得分: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也取决于您; C ++ 17中的if constexpr,在C ++ 11/14中使用或static_if或SFINAE或traits类构造。

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

答案 2 :(得分: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";
}

我知道它不适合特定示例,因为它确实回答了问题。