我想有一个这样的接口函数:
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
上显示错误-似乎不允许从模板typename中获得const_iterator
。我能绕过去吗?
在最坏的情况下,我可以将begin和end迭代器传递给find_index参数,但它看起来不那么好。非常感谢你的优雅解决方案。
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
更好,至少在性能方面。