首页 > 解决方案 > 访问类 Y 中类 X 的可变参数模板参数

问题描述

我有一些图类可以相互继承,以提供不同情况下所需的功能(有向图、可遍历图、嵌套图等)。

为了能够使用最终派生类型,这些派生类型作为模板参数提供给基类​​。这样,例如Edge::GetSource可以返回派生类Node,而不是基类Node

为简单起见,图类仅采用一个模板参数:GraphTypes. GraphTypes反过来将所有需要的派生图类作为模板参数。这使得更改图形类中使用的类型变得非常容易,只需GraphTypes更改即可。

template<class GraphT, class NodeT, class EdgeT>
class GraphTypes {
public:
   using GraphType = GraphT;
   using NodeType = NodeT;
   using EdgeType = EdgeT;
}; // GraphTypes


template<class GraphTypes>
class Edge {
private:
   using GraphType = typename GraphTypes::GraphType;
   using NodeType = typename GraphTypes::NodeType;
   using EdgeType = typename GraphTypes::EdgeType;

public:
   NodeType &GetSource();

protected:
   NodeType *m_pSource;
}; // Edge


template<class GraphTypes>
inline NodeType &Edge<GraphTypes>::GetSource() {
   return *m_pSource;
} // Edge::GetSource

这很好用!但现在我想添加一个可选Context参数。在某些情况下,上下文对象需要在处理图时传递并被告知,例如,何时Edge::SetSource被调用。

我的想法是添加一个可变参数模板参数。这样不需要上下文的图形类就可以省略它。但是如何添加可变参数模板参数GraphTypes,然后在GraphTypes具有模板参数的其他图形类中使用它?

template<class GraphT, class NodeT, class EdgeT, class ...ContextT>
class GraphTypes {
public:
   // error C3520: 'ContextT': parameter pack must be expanded in this context
   using ContextType = ContextT;
}; // GraphTypes


template<class GraphTypes>
class Edge {
private:
   using ContextType = typename GraphTypes::ContextType;

public:
   // error C3543: 'GraphTypes::ContextType': does not contain a parameter pack
   void SetSource(NodeType &Source, ContextType &...Context);
}; // Edge


template<class GraphTypes>
void Edge<GraphTypes>::SetSource(NodeType &Source, ContextType &...Context) {
   if(&Source == m_pSource)
      return;
      
   // I think this should work, but open to suggestions ;)
   std::initializer_list<bool>{ (Context.PreSetSource(*this), true)... };

   m_pSource = &Source;

   std::initializer_list<bool>{ (Context.PostSetSource(*this), true)... };
} // Edge::SetSource

标签: c++templatesvariadic-templates

解决方案


推荐阅读