获取std::vector迭代器的更简便方法
Shorter way to get an iterator for a std::vector
假设我有一个这样的向量
std::vector<a_complicated_whatever_identifier *> *something
= new std::vector<a_complicated_whatever_identifier *>;
// by the way, is this the right way to do this?
现在我想为这个找到一个迭代器…所以我会这样做。
std::vector<a_complicated_whatever_identifier *>::iterator iter;
但是我发现它对我的代码来说有点太多了。我想知道,有没有更简单的方法来请求一个迭代器,而不管它的类型是什么?
我在想。
something::iterator iter;
// OK, don’t laugh at me, I am still beginning with C++
好吧,它显然失败了,但我想你明白了。如何做到这一点或类似的事情?
你通常会给你的容器合理的类型,然后它是一件轻而易举的事:
typedef std::pair<int, Employee> EmployeeTag;
typedef std::map<Foo, EmployeeTag> SignInRecords;
for (SignInRecords::const_iterator it = clock_ins.begin(); ... )
^^^^^^^^^^^^^^^^^
通常,为容器设置一个方便的typedef比为迭代器设置一个显式的typedef更实用,也更具有自文档性(想象一下,如果您要更改容器)。
在新的c++(11)中,您可以使用auto it = clock_ins.cbegin()
来获得一个常量迭代器
使用typedef。
typedef std::vector<complicated *>::iterator complicated_iter
然后像这样设置:
complicated_iter begin, end;
在c++ 11中,你将能够使用auto
。
auto iter = my_container.begin();
同时对vector使用typedef:
typedef std::vector<a_complicated_whatever_identifier *> my_vector;
my_vector::iterator iter = my_container.begin();
你应该很少有直接定义迭代器的需要。特别是,通过集合进行迭代通常应该由泛型算法完成。如果已经定义了一个可以完成这项工作的方法,那么最好使用它。如果没有,最好将自己的算法写成算法。在这种情况下,迭代器类型成为一个模板形参,使用您喜欢的任何名称(通常至少松散地引用迭代器类别):
template <class InputIterator>
void my_algorithm(InputIterator start, InputIterator stop) {
for (InputIterator p = start; p != stop; ++p)
do_something_with(*p);
}
既然它们已经被提到了,我将指出IMO, typedef
和c++ 11的新auto
(至少IMO)很少是这种情况的好答案。是的,它们可以消除(或至少减少)定义迭代器类型对象的冗长——但在这种情况下,它基本上只是治疗症状,而不是疾病。
作为题外话,我还要注意:
- 指针向量通常是错误的。动态分配矢量更有可能是错误的。
至少现在,看起来好像您可能已经习惯了Java之类的东西,在Java中,总是必须使用new
来创建对象。在c++中,这是相对不常见的——大多数时候,您只想定义一个局部对象,以便自动处理创建和销毁。
//顺便问一下,这是正确的方法吗?
你所做的是正确的。最好的方法取决于你想如何使用这个向量。
但是我发现它对我的代码来说有点太多了。我想知道,有没有更简单的方法来请求迭代器而不管类型是什么?
可以,可以将vector定义为类型:
typedef std::vector<a_complicated_whatever_identifier *> MyVector;
MyVector * vectPtr = new MyVector;
MyVector::iterator iter;
如果你有一个最新的编译器,我建议你试试c++11。大多数编译器以--std=c++0x
标志的形式支持它。您可以做各种与类型推断相关的有趣的事情:
std::list<std::map<std::string, some_complex_type> > tables;
for (auto& table: tables)
{
std::cout << table.size() << std::endl;
}
for (auto it = tables.begin(); it!= tables.end(); ++it)
{
std::cout << it->size() << std::endl;
}
也看一下decltype和许多其他的便利:
// full copy is easy
auto clone = tables;
// but you wanted same type, no data?
decltype(tables) empty;
将typedef与上面的组合的人为示例:
typedef decltype(tables) stables_t;
typedef stables_t::value_type::const_iterator ci_t;
- 使用迭代器替换映射中的常量项的方法
- 创建可以遍历 std::map 值的通用模板迭代器的最简单方法是什么?
- 从基于迭代器的for循环转换后,如何在map::find()中调用方法
- 在 C++17 中实现迭代器和const_iterator的正确方法是什么?
- 编译错误 std::vector<std::shared_ptr<T>>迭代器和擦除方法
- 如何使用 SFINAE 从 end() 方法返回 (const_) 迭代器
- 如何使用迭代器作为参数方法?
- 迭代器方法无法从Const_iterator继承
- 是否有一种方法可以使用Boost Serialization序列化迭代器
- 有关使用矢量迭代器访问对象方法的问题
- 如何从内联模板方法返回通用矢量迭代器
- 初始化迭代器的最佳方法是什么?
- 无法将迭代器传递给 C++ 中的类方法
- 返回迭代器内容并将其递增的简单方法
- 实现迭代器通用方法的正确方式
- 迭代器回到递归方法的开头
- 使用矢量迭代器访问方法
- C++迭代器作为类方法中使用的类成员
- C++ 迭代器与对象与 length() 方法
- 迭代器无法访问派生类的成员方法