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

Alternatives for std::enable_if and explicit overloading for template template parameters

本文关键字:重载 方案 参数 if std enable      更新时间:2023-10-16

考虑以下设置:

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破解?

    1. 重复的代码会重复错误,所以它不是最佳的
    2. 在我的情况下,std::enable_if会产生错误消息

有没有一个更聪明的解决方案可以让f接受常量和非常量节点?

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

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

T将被推导为Node<Foo>vNode<Foo>const Node<Foo>等。如果NodevNode很重要,那么您总是可以使用一个简单的trait类来提取节点的类型。类似地,您可以将static_assert与trait类一起使用,以确保TNodevNode的专门化。