Why are the Container Adapters like std::stack or std::queue implemented as adapters and not as independent containers? Is it because you want e.g. a stack with an underlying memory managment of different Sequence Containers?
Why are the algorithms of the STL implemented as free functions, which expect iterators, and not as methods of the corresponding containers?
This is done to give programmers better control over the implementation. An ability to mix-and-match is incredibly powerful, because it lets you achieve more things with less code.
Why are the Container Adapters like std::stack or std::queue implemented as adapters
Because you can mix-and-match containers and adapters: depending on your needs, you can create a queue based on a vector, or a stack based on a list, and then change the implementation details by swapping in a container of different type.
Why are the algorithms of the STL implemented as free functions
To avoid coding them in multiple places. For example, a linear search in a vector remains the same linear search in a list, and can also be applied to other containers that have iterators.
Note that some containers do have member-functions specific to their implementation. For example, std::set has find method for faster non-linear search.
Related
Let's assume I have a function that accepts a container and uses the .insert or .find on it, meaning it is either unordered associative container, or associative container.
Is there a common C++ name for this kind of containers?
To my knowledge, none of the proposals for adding concepts to the standard library conceptualize the containers themselves. They conceptualize iterators and ranges, along with algorithm versions that use those concepts. And the containers can use concepts for various things.
But there aren't concepts for detecting the capabilities of a container beyond their range capacities.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why would I prefer using vector to deque
I am curious why is it that std::vector is so much more popular than std::deque. Deque is almost as efficient in lookup, more efficient in insert (without vector::reserve)and allows for inserting/deleting in the front.
Herb Sutter once recommended that if you want to use vector, just prefer deque (I am paraphrasing). However in a recent talk on Writing Modern C++ he again strongly recommends thinking of std::vector as a default container. According to the GOTW I linked earlier, even the standard has similar wording.
Is there a reason for this disparity? Is it just that vector is simpler and more well known, or is there a technical reason? Or is it that vector is just a cooler name .. ?
I can't speak for anybody else, but I can for myself.
When I first read about std::deque, I thought it was cool enough that for a while, I treated it not only as the default container, but as nearly the only container I used.
Then somebody asked about why, and I expounded at length on its virtues and why it was the best container to use for practically everything, and how it was much more versatile than std::vector.
Fortunately, the guy questioning my decision on it was persuasive enough that I did some testing. Testing showed that in nearly every case, std::deque was slower than std::vector -- often by a substantial factor (e.g., around 2). In fact, of the code I'd written using std::deque, just replacing std::deque with std::vector gave a speedup in all but a handful of cases.
I have used std::deque in a few cases since then, but definitely don't treat it as the default any more. The simple fact is that in the usual implementation it's noticeably slower than std::vector for most purposes.
I should add, however, that I'm reasonably certain that with the right implementation, it could be nearly equivalent to std::vector in virtually all cases. Most use a representation that's undoubtedly great from an asymptotic viewpoint, but doesn't work out quite so wonderfully (for many purposes) in the real world.
std::vector is very well understood, simple and is compatible with C (both in terms of the memory layout, and in terms of using pointers as iterators).
For some operations it is also more efficient than std::deque. Accessing elements by index is one example.
For a given task, it makes sense to use the simplest container that does the job well. In many cases that simplest container is std::vector.
People use std::vector over std::deque for a simple reason. They interface with a lot of C libraries and they have functions with parameters which require a pointer to contiguous storage, which std::deque doesn't (can't) guarantee.
Another reason is when you build code according to std::deque and your requirements change so that you have to support contiguous access, you will have a bit of refactoring to do.
I am compelled to mention that there are libraries out there whose authors claim to have created more efficient vector implementations in order to overcome inefficiencies when capacity is increased.
The structure of std::deque is a bit more complex which makes naive iteration quite a bit more expensive than std::vector. The insertions into std::vector with its reallocations tend not to be big problem, especially when using reserve() and only appending to the end. Also, there are easier to understand invalidation rules for std::vector although it is actually an advantage of std::deque that objects stay put when inserting/removing only at either end (note that std::deque iterators get invalidate upon each insertion, independent of where the insertion happens). Another plus for std:vector is the guarantee that the values are contiguous in memory causing it to make fewer memory allocations.
I guess, I would recommend use of std::deque algorithms were consistently optimized to use segmented sequences (I'm not aware that any standard C++ library does this optimization) and users were accessing sequences consistently using algorithms (as far as I can tell, only a tiny fraction of users considers the option to use algorithms). Otherwise I would suspect that std::deque is the better option with respect to performance only if you take advantage of its specific properties (e.g., that objects stay put and that you can insert/remove at the end). It is worth profiling the two alternatives, though.
Apart from std::vector being the most commonly known container class, it also has several advantages over std::deque, namely:
A typical std::deque requires an additional indirection to access the elments unlike as in case of std::vector.
Iterators in case of std::deque must be smart pointers and not pointers as in case of std::vector.
Elements of an std::vector are guaranteed to be contiguous and hence it is compatible with c-style functions which take arrays as parameters.
std::deque provide no support to control the capacity and the moment of reallocation.
Especially, the last point is noteworthy.
According to Bjarne Stroustrup's slides from his Going Native 2012 keynote, insertion and deletion in a std::list are terribly inefficient on modern hardware:
Vector beats list massively for insertion and deletion
If this is indeed true, what use cases are left for std::list? Shouldn't it be deprecated then?
Vector and list solve different problems. List provides the guarantee that iterators never become invalidated as you insert and remove other elements. Vector doesn't make that guarantee.
Its not all about performance. So the answer is no. List should not be deprecated.
Edit Beyond this, C++ isn't designed to work solely on "modern hardware." It is intended to be useful across a much wider range of hardware than that. I'm a programmer in the financial industries and I use C++, but other domains such as embedded devices, programmable controllers, heart-lung machines and myriad others are just as important. The C++ language should not be designed solely with the needs of certain domains and the performance of certain classes of hardware in mind. Just because I might not use a list doesn't mean it should be deprecated from the language.
Whether a vector outperforms a list or not also depends on the type of the elements. For example, for int elements vector is indeed very fast as most of the data fits inside the CPU cache and SIMD instructions can be used for the data copying. So the O(n) complexity of vector doesn't have much impact.
But what about larger data types, where copying doesn't translate to a stream operation, and instead data must be fetched from all over the place? Also, what about hardware that doesn't have large CPU caches and possibly also lacks SIMD instructions? C++ is used on much more than just modern desktop and workstation machines. Deprecating std::list is out of the question.
What Stroustrup is saying in that presentation is that before you pick std::list for your data, you should make sure that it's the right choice for your particular situation. In other words, benchmark and profile. It definitely doesn't say you should always pick std::vector.
No, and especially not based on one particular graph. There are instances where list will perform better than vector. See: http://www.baptiste-wicht.com/2012/12/cpp-benchmark-vector-list-deque/
And that's ignoring the non-performance differences, as others have mentioned.
Bjarne's point in that talk wasn't that you shouldn't use list. It was that people make too many assumptions about list's performance that often turn out to be wrong. He was simply justifying the stance that vector should always be your default go-to container type unless you actually find a need for the performance or other semantic characteristics of lists.
std::list is a deque, it has push_front() and pop_front(). It still has a niche role as such, though it may not be the best choice for a deque.
std::list does not reallocate memory, while std::vector may. Sometimes you don't want an item to move in memory (e.g. a stackful coroutine).
Linked lists are related to tree data structures. Both contain links. If we deprecate std::list, then what about tree-based containers?
Of course not. std::list is a different data structure. Comparing different data structure is good indication of its properties, advantages or disadvantages. But each data structure has its advantage.
I'm already aware of the following:
arrays
bitsets
hash maps and sets
regular maps and sets
iterators
lists
pairs
tuples
queues, deques, and priority queues
stacks
valarrays
vectors
Is there any other type of data structure available in the C++ library. What I'm specifically looking for is graphs, but I'd also like to know what else is there.
Also, I'd like to know if there are any external libraries I can link with my projects to implement a graph.
It's "the C++ standard library" or something to that effect, not "the STL". That term refers to an initial draft of some specific data structures and algorithms. Not all of them made it into the standard library, and the standard library also contains other stuff (for example, all the iostream classes).
That looks like a complete list to me (you appear to be talking specifically about C++0x, since you mention tuples and arrays). I don't know if I would even consider bitsets and iterators to be "data structures", but I guess that's a fair description.
There is definitely not a graph implementation. Unfortunately. :( You can get one from Boost, though.
The STL is divided into three parts:
Containers
Iterators
Algorithms
You have obviously found the containers part and you have probably used the iterators associated with the containers. But there is even more to the iterators than you have found.
The algorithms sections is linked to the containers via iterators. But also contains the parts handle functors and associated binders.
My favortie site for this is: http://www.sgi.com/tech/stl/table_of_contents.html
In addition to the standard libraries you should have a look at the boost libraries:
see also: Boost Library
I'm developing a OpenGL based simulation in C++. I'm optmizing my code now and i see throughout the code the frequently use of std:list and std:vector. What is the more performatic: to continue using C++ stl data structs or a pointer based linked list? The main operation that involve std::list and std::vector is open a iterator and loop through all items in the data structs and apply some processing
How about stl containers of pointers?
It is highly unlikely that you will be able to develop better performing structures than the builtin. The only down part is the containers actually do contain copies of objects stored in them. If you're worried about this memory overhead (multiple structs hodling multiple copies of same objects, breaking consistency across the table) you should think about using stl structures of pointers to what you need.
Algorithmically speaking, the structure you need is implemented in the stl so you should use it. There is no need to reimplement the same structure.
Use C++ STL data structs, but use them efficiently. If you're using std::list and std::vector, look up such functions as find, for_each, accumulate, etc.
Here's some good reading:
http://www.cplusplus.com/reference/
Read the sections on algorithm, numeric, and functional. Also, I strongly recommend Scott Meyers' Effective STL.