简体   繁体   中英

std::vector::insert vs std::list::operator[]

I know that std::list::operator[] is not implemented as it has bad performance. But what about std::vector::insert it is as much inefficient as much std::list::operator[] is. What is the explanation behind?

std::vector::insert is implemented because std::vector has to meet requirements of SequenceContainer concept , while operator[] is not required by any concepts (that I know of), possible that will be added in ContiguousContainer concept in c++17. So operator[] added to containers that can be used like arrays, while insert is required by interface specification, so containers that meet certain concept can be used in generic algorithms.

I think Slava's answer does the best job, but I'd like to offer a supplementary explanation. Generally with data structures, it's far more common to have more accesses than insertions, than vice versa. There are many data structures that may try to optimize access at the cost of insertion, but the inverse is much more rare, because it tends to be less useful in real life.

operator[] , if implemented for a linked list, would access an existing value presumably (similar to how it does for vector ). insert adds new values. It's much more likely you will be willing to take a big performance hit to insert some new elements into a vector , provided that the subsequent accesses are extremely fast. In many cases, element insertion may be outside of the critical path entirely whereas the critical path consists of a single traversal, or random access of already-present data. So it's simply convenient to have insert take care of the details for you in that case (it's actually a bit annoying to write efficiently and correctly). This is actually a not-uncommon use of a vector.

On the other hand, using operator[] on a linked list would almost always be a sign that you are using the wrong data structure.

std::list::operator[] would require an O(N) traversal and is not really in accordance with what a list is designed to do. If you need operator[] then use a different container type. When C++ folk see a [] they assume an O(1) (or, at worse, an O(Log N)) operation. Supplying [] for a list would break that.

But although std::vector::insert is also O(N), it can be optimised: an at-end insertion can be readily optimised by having the vector 's capacity grow in large chunks. An insertion in the middle requires an element-by-element move, but that again can be performed very quickly on modern chipsets.

The [] operator is inherited from plain arrays. It has always been understood as a fast (sub linear time) accessor of the underlying container. Since list is does not support sub linear time access, it does not make sense for it to implement the operator.

auto a = Container [10]; // Ideally I can assume this is quick

The equivalent of your std::list <>::operator [] is std::next <std::list<>::iterator> . Documented at cpp-reference .

auto a = *std::next (Container.begin (), 10); // This may take a little while

This is the truly generic way index a container. If the container supports random access, it will be constant time, other wise it will be linear.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM