考虑以下设置:
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
时,我希望它是常量中性的(在图中节点的常量和非常量版本上执行相同的操作,但在分支和非分支节点上不同图)。我必须:
- 复制代码?
使用
std::enable_if
hack?- 重复代码会重复错误,因此不是最优的。
- std::enable_if 在我的案例中会产生错误消息。
对于使 f
接受 const 和非常量节点的问题,是否有更智能的解决方案?
最佳答案
与其使用模板模板参数和大量重载,不如使用类型模板参数:
template<class T> void f( Graph<T> ) { /*...*/ }
T
将被推断为 Node<Foo>
, vNode<Foo>
或 const Node<Foo>
等等。如果Node
对比vNode
重要的是,您始终可以使用简单的特征类提取节点的类型。同样,您可以使用 static_assert
与特征类一起确保 T
是 Node
的特化或 vNode
.
关于c++ - std::enable_if 的替代方案和模板模板参数的显式重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25780575/