获取std :: vector的迭代器的更短方法

时间:2011-09-21 19:39:08

标签: c++ vector iterator std stdvector

让我们说我有这样的矢量。

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++

嗯,它显然失败了,但我想你明白了。如何实现这个或类似的东西?

6 个答案:

答案 0 :(得分:11)

你通常会给你的容器明智的typedef,然后它是轻而易举的:

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()来获得一个const-iterator。

答案 1 :(得分:8)

使用typedef。

typedef std::vector<complicated *>::iterator complicated_iter

然后像这样设置它们:

complicated_iter begin, end;

答案 2 :(得分:7)

在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();

答案 3 :(得分:1)

很少有很多需要/用于直接定义迭代器。特别是,迭代通过集合通常应该通过通用算法来完成。如果已经定义了一个可以完成这项工作的工作,那么最好使用它。如果没有,最好将自己的算法编写为算法。在这种情况下,迭代器类型将成为一个模板参数,您可以选择任何您喜欢的名称(通常至少可以指代迭代器类别):

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)很少能很好地回答这种情况。是的,他们可以消除(或至少减少)定义迭代器类型对象的冗长度 - 但在这种情况下,它基本上只是治疗症状,而不是疾病。

顺便说一句,我还要注意:

  1. 指针向量通常是个错误。
  2. 动态分配矢量更可能是一个错误。
  3. 至少马上,看起来好像你已经习惯了类似Java的东西,你总是必须使用new来创建一个对象。在C ++中,这是相对不寻常的 - 大多数情况下,您只想定义一个本地对象,以便自动处理创建和销毁。

答案 4 :(得分:0)

  

//顺便问一下,这是正确的方法吗?

你在做什么是正确的。最好的方法取决于您希望如何使用该向量。

  

但我觉得我的代码有点太多了。我想知道,有没有   更多,无论类型如何都要求迭代器的简短方法?

是的,您可以将矢量定义为类型:

typedef std::vector<a_complicated_whatever_identifier *> MyVector;
MyVector * vectPtr = new MyVector;
MyVector::iterator iter;

答案 5 :(得分:0)

如果你有一个最近的编译器,我建议给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;