std::enable_if和模板模板参数显式重载的替代方案
Alternatives for std::enable_if and explicit overloading for template template parameters
考虑以下设置:
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
破解?- 重复的代码会重复错误,所以它不是最佳的
- 在我的情况下,std::enable_if会产生错误消息
有没有一个更聪明的解决方案可以让f
接受常量和非常量节点?
与其使用模板模板参数并有大量重载,不如使用类型模板参数:
template<class T> void f( Graph<T> ) { /*...*/ }
T
将被推导为Node<Foo>
、vNode<Foo>
或const Node<Foo>
等。如果Node
和vNode
很重要,那么您总是可以使用一个简单的trait类来提取节点的类型。类似地,您可以将static_assert
与trait类一起使用,以确保T
是Node
或vNode
的专门化。
相关文章:
- 继承函数的重载解析
- 运行同一解决方案的另一个项目的项目
- 你能重载对象变量名本身返回的内容吗
- 从父命名空间重载类型
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- Project Euler问题4的错误解决方案
- 重载操作程序时出错>>用于类中的字符串 memebr
- 一个关于在C++中重载布尔运算符的问题
- 不同翻译单元中不可重载的非内联函数定义
- 为什么使用SFINAE而不是函数重载
- 模板重载解决方案:当多个模板匹配时会发生什么?
- 模板和unique_ptr继承情况下的重载解决方案
- 视觉工作室中涉及 void*、字符串和常量字符 [] 的意外重载解决方案
- C++构建一个带有运算符重载的双边树-什么是好的内存解决方案
- 单例方案,使用不同的参数重载 getInstance
- 模板函数重载解决方案
- 重载 C++ 中的输入流我的解决方案中出了什么问题
- std::enable_if和模板模板参数显式重载的替代方案
- c++中按引用传递和按值传递之间重载歧义的实用解决方案