2

考虑这两个函数,它们适用于 std::vector:

  int connectNode(GraphNode const& newNode,std::vector<GraphNode const*>::const_iterator beginCandidates, std::vector<GraphNode const*>::const_iterator endCandidates){
    int connections =0;
    for (auto iter= beginCandidates; iter!=  endCandidates; ++iter) {
      if(connectNodes(newNode,**iter)) ++connections;
    }
    return connections;
  }

  int connectNode(GraphNode const& newNode,std::vector<GraphNode>::const_iterator beginCandidates, std::vector<GraphNode>::const_iterator endCandidates){
    int connections =0;
    for (auto iter= beginCandidates; iter!=  endCandidates; ++iter) {
      if(connectNodes(newNode,*iter)) ++connections;
    }
    return connections;
  }

这些函数适用于向量,但显然不适用于任何其他容器,例如集合。怎么可能一概而论。我能想到的唯一可能的解决方案是使用一些非常丑陋的 enable_if 解决方法。有直接的解决方案吗?编辑:为了更清楚:我想要两个功能,一个用于普通容器,一个用于指针容器。真正的逻辑发生在 connetNodes 内部,它需要两个引用。(注意第一个函数中的**)

4

2 回答 2

2

如前所述,使迭代器类型成为模板参数 - 这解决了泛化迭代器本身的问题。GraphNode对于正常值及其指针之间的差异,您可以使用重载:

template<class T>
T& maybe_deref(T& v){ return v; }

template<class T>
T& maybe_deref(T* p){ return *p; }

只需调用它connectNodes(newNode, maybe_deref(*iter))

于 2013-03-20T22:25:22.417 回答
2

把迭代器作为模板参数,那么你就不用担心你迭代的是什么类型的容器。

template<class T, class Iter>
int connectNode( GraphNode const& newNode, 
                 Iter beginCandidates, 
                 Iter endCandidates )
{
  // ...
}

我没有看到T函数模板中的任何地方使用了其他模板参数 (),但我假设您的真实代码在某处使用它。

此外,您可以static_assert将迭代器指向GraphNode const*usingstd::iterator_traits<Iter>::value_type

static_assert( std::is_same< typename std::iterator_traits<Iter>::value_type
                             GraphNode const *>::value,
               "Iterator must point to 'GraphNode const *'" );

编辑:

为了能够接受指向GraphNodeGraphNode const *保持函数模板签名相同的迭代器,但为调用的助手创建 2 个重载connectNodes

bool do_connectNodes( GraphNode const& newNode, GraphNode const *p )
{
  return connectNodes( newNode, *p );
}

bool do_connectNodes( GraphNode const& newNode, GraphNode& n )
{
  return connectNodes( newNode, n );
}

现在,connectNodeif条件更改为

if( do_connectNodes(newNode,*iter) ) ++connections;

并且将根据迭代器指向的内容选择正确的重载。

于 2013-03-20T22:00:28.407 回答