A shorter way to get an iterator for std :: vector

Let's say that I have such a 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? 

Now I want to get an iterator for this ... so I would do it like this.

 std::vector<a_complicated_whatever_identifier *>::iterator iter; 

But I find this too big for my code. I wonder if there is an even shorter way to request an iterator, regardless of type?

I was thinking of something like.

 something::iterator iter; // OK, don't laugh at me, I am still beginning with C++ 

Well, this clearly won't succeed, but I think you get the point. How to accomplish this or something similar?

+6
source share
6 answers

Use typedef.

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

Then install them as follows:

 complicated_iter begin, end; 
+8
source

Usually you give your containers reasonable typedefs and then the wind:

 typedef std::pair<int, Employee> EmployeeTag; typedef std::map<Foo, EmployeeTag> SignInRecords; for (SignInRecords::const_iterator it = clock_ins.begin(); ... ) ^^^^^^^^^^^^^^^^^ 

Usually having a convenient typedef for a container is more practical and self-documenting, which is an explicit typedef for an iterator (imagine if you are changing a container).

With new C ++ (11), you can say auto it = clock_ins.cbegin() to get a const iterator.

+11
source

In C ++ 11, you can use auto .

 auto iter = my_container.begin(); 

In the meantime, just use typedef for the vector:

 typedef std::vector<a_complicated_whatever_identifier *> my_vector; my_vector::iterator iter = my_container.begin(); 
+7
source

You rarely need to use an iterator to directly define it. In particular, iteration through a collection should usually be performed using a general algorithm. If it is already defined there that can carry out this work, it is best to use it. If not, it is better to write your own algorithm as an algorithm. In this case, the iterator type becomes a template parameter with any name that you prefer (as a rule, something belongs, at least, to the iterator category):

 template <class InputIterator> void my_algorithm(InputIterator start, InputIterator stop) { for (InputIterator p = start; p != stop; ++p) do_something_with(*p); } 

Since they were mentioned, I will point out that IMO, typedef and C ++ 11 new auto (at least IMO) are rarely a good answer to this situation. Yes, they can eliminate (or at least reduce) verbosity when defining an object like an iterator, but in this case it basically just considers the symptom, not the disease.

As an aside, I would also like to note that:

  • Pointer vector is usually an error.
  • Dynamic distribution of the vector is an even more likely error.

At least right away, it looks like you're probably used to something like Java, where you always need to use new to create the object. In C ++, this is relatively unusual - most of the time you just want to define a local object, so creation and destruction will be processed automatically.

+1
source

// By the way, is this the right way to do this?

What you do is right. The best approach depends on how you want to use this vector.

But I find this too big for my code. I wonder if there is any shorter way to request an iterator, regardless of type?

Yes, you can define a vector as a type:

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

If you have a recent compiler, I suggest using C ++ 11. Most compilers support it in the form of the flag --std=c++0x . You can do all kinds of elegant things related to the type of output:

 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; } 

Also look at decltype and many other features:

 // full copy is easy auto clone = tables; // but you wanted same type, no data? decltype(tables) empty; 

A far-fetched example of combining typedefs with the above:

 typedef decltype(tables) stables_t; typedef stables_t::value_type::const_iterator ci_t; 
0
source

Source: https://habr.com/ru/post/897779/


All Articles