1
考慮以下設置:替代品的std :: enable_if和模板的模板明確的重載參數
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
接受const和non-const的節點?
爲什麼不簡單地'template void f(圖)'並且讓'T'被適當地推導出來?您可以隨時使用特徵類輕鬆提取節點類型。 –
2014-09-11 11:30:13
爲什麼'Graph < node_t >'和'Graph>'如果它們具有不同的實現,接口並且使用方法不同,那麼它們是'相同'模板?還是有對待他們的功能相同?例如,您可以編寫一個工廠模板,根據它是否爲終端返回不同的類型。 –
Yakk
2014-09-11 14:11:32
@Yakk:有兩個原因:1.一個'Graph'來自'Branch <>',它是一個'std :: tuple'包裝器。由於'std :: tuple <>'不是零大小,我認爲空基優化不適用。 2.有遍歷'Graph'的遞歸函數,並且在終端節點上終止它們需要函數超載。 Graph>'的重載與'Graph '沒有多大區別,後者產生更短的錯誤並且意圖更明確。 @TC:這是一個很好的想法,我去了。一如既往地感謝你,這應該作爲答案發布。 –
tsuki
2014-09-11 14:29:57