std::vector operator [] is evil?

Started by
24 comments, last by werekarg 18 years, 9 months ago
Quote:Original post by JY
Quote:Original post by snk_kid
If you don't declare your variables as of reference type then a copy will be made...


But this isn't true for vectors?


[rolleyes] what exactly do you mean? as i said before both of vector/map's overloaded subscript operators return constant and non constant reference to there elements, this is exactly the same semantics as C-style arrays in C++. Do you understand what l-values & r-values are?

When you access an element of an array of T in the context of an r-value the type is const T&.
When you access an element of an array of T in the context of an l-value the type is T& or const T& if the array has been declared constant.

If that still doesn't make sense take this example:


foo bar[N]; // a C-style array

foo foo_val = bar[0]; // a copy is made of the first element

const foo& const_foo_ref = bar[0]; // refers to the first element, no copy its the original.

foo& foo_ref = bar[0]; // refers to the first element, no copy its the original.


And the same holds for vector/map.
Advertisement
Quote:Original post by Anonymous Poster
Quote:Original post by JY
Quote:Original post by snk_kid
If you don't declare your variables as of reference type then a copy will be made...


But this isn't true for vectors?


[rolleyes] what exactly do you mean? as i said before both of vector/map's overloaded subscript operators return constant and non constant reference to there elements, this is exactly the same semantics as C-style arrays in C++. Do you understand what l-values & r-values are?

When you access an element of an array of T in the context of an r-value the type is const T&.
When you access an element of an array of T in the context of an l-value the type is T& or const T& if the array has been declared constant.

If that still doesn't make sense take this example:


foo bar[N]; // a C-style array

foo foo_val = bar[0]; // a copy is made of the first element

const foo& const_foo_ref = bar[0]; // refers to the first element, no copy its the original.

foo& foo_ref = bar[0]; // refers to the first element, no copy its the original.


And the same holds for vector/map.



That was me, i was logged out for unknown reasons again [headshake].

Anyways those people who keep saying vector's subcript operator and vector itself is slow are talking rubbish:


  • vector's subscript operator does not check bounds (except maybe in debug builds). If you want bounds checking use vector's at method.

  • On modern C++ compilers with good standard compliance, with optimizations on vector is equivalent to a C-style dynamic in efficiency, infact in typical implementations of vector, when optimizations are on it will compile out to a cleverly used/manipulated C-style dynamic array.



[Edited by - snk_kid on June 30, 2005 5:47:27 AM]
hmm but most times we use [] operator we r using it cuz we need a random access iterator and not to loop through all the list using a normal iterator, this is where [] is very useful. so in new compilers it can be as useful as begin()+i
Quote:Original post by tolaris
You might want to cache the result of .end() to a const_iterator and compare with it, rather than evaluate the size of your vector couple hundred times ^^;


That's a good idea. I never thought about doing that.
Quote:
You might want to cache the result of .end() to a const_iterator and compare with it, rather than evaluate the size of your vector couple hundred times ^^;


Quote:
One thing I noticed while looking at your code is that you post-increment the iterator in your for loop(ex. iter++ ). You should get in the habit of pre-incrementing any non-trivial data tpyes(ex. ++iter). This could speed thing up more.


It's good to get into the habit of doing these thing, but don't expect the code produced to be any faster when compiled with an optimizing compiler.
not [] related: you should avoid calling glBindTexture for each primitive rendering, try keeping the surfaces "grouped" by texture.

Quote:You might want to cache the result of .end() to a const_iterator and compare with it


in the implementation of stl i have (included in borland c++builder 6), begin and end for vector read:

  iterator begin()             { return this->_M_start; }  iterator end()               { return this->_M_finish; }


not a big improvement to cache end() result, aside from a method call which will probably get inlined anyway. might aswell try to cache the begin() result.

This topic is closed to new replies.

Advertisement