2011-10-28 55 views
3

我想和接口的功能是这样的:查找迭代器的指数在STL容器 - 需要模板函数

template<typename T, typename R> int find_index (const T& list, const R& value); 

据我所知,有在STL返回迭代器find()。我需要返回迭代器的索引(即使对于非索引容器,例如std::list)。我想这样的代码:

template<typename T, typename R> 
int find_index (const T& list, const R& value) 
{ 
    int index = 0; 
    for (T::const_iterator it = list.begin(); it != list.end(); it++, index++) 
     if ((*it) == value) 
      return index; 
    return -1; 
} 

但是编译器显示了it错误 - 好像它是不允许从模板类型名获得const_iterator。我可以绕过吗?

在最糟糕的情况下,我可以通过开始和结束迭代器find_index参数,但它看起来不那么好。会感谢优雅的解决方案。

回答

11
for (typename T::const_iterator it = list.begin(); it != list.end(); ++it, ++index) 

应该解决你的问题。

当使用依赖类型(取决于模板参数类型),编译器不知道const_iterator是一种类型,直到它用实例化一个具体类型的模板,它也可能只是一个静态变量或什么的。使用typename关键字,你告诉他const_iterator确实是一种类型。

在C++ 11你也可以使用关键字auto规避整个typename问题:

for (auto it = list.begin(); it != list.end(); ++it, ++index) 

如果你已经有了迭代器(也许从一些其他的操作),用户也可以直接从列表中的计算距离开始这个迭代:

#include <iterator> 

int index = std::distance(list.begin(), it); 

但由于这具有线性复杂的std::list,使用您的自制find_index功能比std::find接着std::distance至少在性能方面更好。