c++ - std::enable_if 的替代方案和模板模板参数的显式重载

标签 c++ templates c++11 template-meta-programming overload-resolution

考虑以下设置:

template< typename Held >
class Node{
  //...
};

template< typename Held >
class vNode{
  //...
};

template <typename... Graphs>
class Branch{
  //...
};

template <typename...> class Graph; // undefined

template< 
  typename    node_t
> class Graph< node_t >{  //specialization for an ending node
  //...
};

template< 
  typename    node_t,
  typename... Graphs
> class Graph< node_t, Branch< Graphs...> >{  //specialization for a mid-graph node
  //...
};

template<
  template <typename> class node_t,
  typename Held
> void f( Graph< Node<Held> > ) {
  //stuff A on a node
}

template<
  template <typename> class node_t,
  typename Held
> void f( Graph< const Node<Held> > ) {
  //stuff A on a const node
}

template<
  template <typename> class node_t,
  typename Held
> void f( Graph< vNode<Held> > ) {
  //stuff B on a virtual node
}

template<
  template <typename> class node_t,
  typename Held
> void f( Graph< const vNode<Held> > ) {
   //stuff B on a virtual const node
}

template<
  template <typename> class node_t,
  typename Held,
  typename... Graphs
> void f( Graph< Node<Held>, Branch<Graphs...>> ) {
  //stuff C on a node with a branch
}

template<
  template <typename> class node_t,
  typename Held,
  typename... Graphs
> void f( Graph< const Node<Held>, Branch<Graphs...> > ) {
  //stuff C on a const node with a branch
}

template<
  template <typename> class node_t,
  typename Held,
  typename... Graphs
> void f( Graph< vNode<Held>, Branch<Graphs...> > ) {
  //stuff D on a virtual node with a branch
}

template<
  template <typename> class node_t,
  typename Held,
  typename... Graphs
> void f( Graph< const vNode<Held>, Branch<Graphs...> > ) {
   //stuff D on a virtual const node with a branch
}

换句话说,我正在创建一个代表图形的类型。节点可以是普通的、虚拟的、常量的和非常量的。图可以包含单个节点,或节点和图的分支。

当我创建函数 f 时,我希望它是常量中性的(在图中节点的常量和非常量版本上执行相同的操作,但在分支和非分支节点上不同图)。我必须:

  1. 复制代码?
  2. 使用 std::enable_if hack?

    1. 重复代码会重复错误,因此不是最优的。
    2. std::enable_if 在我的案例中会产生错误消息。

对于使 f 接受 const 和非常量节点的问题,是否有更智能的解决方案?

最佳答案

与其使用模板模板参数和大量重载,不如使用类型模板参数:

template<class T> void f( Graph<T> ) { /*...*/ }

T将被推断为 Node<Foo> , vNode<Foo>const Node<Foo>等等。如果Node对比vNode重要的是,您始终可以使用简单的特征类提取节点的类型。同样,您可以使用 static_assert与特征类一起确保 TNode 的特化或 vNode .

关于c++ - std::enable_if 的替代方案和模板模板参数的显式重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25780575/

相关文章:

c++ - 可变参数模板 模板

c++ - 即使在 std::shared_ptr 拥有之后,shared_from_this 还是空的 _M_weak_this

c++ - 在 C 项目中使用 C++ 库会导致一长串错误

c++ - 自定义类的优先级队列

c# - monodevelop System.DllNotFoundException 调用 C++ 库中的函数

c++ - 错误 C2248 : strange error when I use thread

c++ - 学习 C++ 模板

c++ - 虚拟模板函数: implementing the Visitor pattern with parameters

c++ - 模板化方法的未解决符号特化

c++ - 为什么 C++11 中的统一初始化在虚拟基类中表现得很奇怪?