C++ iterators considered harmful? - c++

At the Boost library conference today, Andrei Alexandrescu, author of the book Modern C++ Design and the Loki C++ library, gave a talk titled "Iterators Must Go" (video, slides) about why iterators are bad, and he had a better solution.
I tried to read the presentation slides, but I could not get much out of them.
Are iterators bad?
Is his replacement really better?
Will C++ implementators pick up his ideas?

First, to answer your questions:
No. In fact, I argued elsewhere that iterators are the most important/fundamental concept of computer science ever. I (unlike Andrei) also think that iterators are intuitive.
Yes, definitely but that shouldn't come as a surprise.
Hmm. Looking at Boost.Range and C++0x – haven't they already?
Andrei's big contribution here is just to say: drop the concept of iterators altogether, see ranges not just as a convenience wrapper but rather as a core construct. Other languages have already done this (much of Andrei's concepts just echo .NET's LINQ or Python's iterators) but they all only offer output ranges. Andrei argues for different types of ranges, much like the conventional iterator categories.
In that light, it's odd that he starts by mocking the arbitrariness of these iterator categories.
I also think that his examples are off, especially his file copying: yes, the iterator variant is a huge improvement over the 1975 code. It reduces a loop with complicated break condition down to one statement. What he's really taking issue with here is just the syntax. Well, excuse me: we're talking about C++ here – of course the syntax is ugly. And yes, using ranges here is an improvement – but only syntactically.
I also think that Andrei's find implementation is off. What he really defines there is the DropUntil operation (naming is hard!) from LINQ. The find operation should really return either one or zero elements (or an iterator!). Shunning iterators here isn't helpful in my opinion since we might want to modify the value directly instead of copying it. Returning a one-element range here only adds overhead without a benefit. Doing it Andrei's way is bad because then the name of the method is just wrong and misleading.
That said, I essentially agree with Andrei in almost all points. Iterators, while being my pet concept from computer science, are certainly a big syntactical burden and many ranges (especially infinite generators) can (and should) be implemented conveniently without them.

I agree with him that iterators are mostly inferior to ranges, and I don't know if 'something better' will get picked up.
"The good is the enemy of the best" is strongly at play here, as it usually is. Iterators are useful and firmly entrenched, so it's hard to know if something better like ranges can supplant them in a reasonable amount of time.

Most of us make a simple use of them in what have become well known idioms, like in for loops to iterate through an std::vector. A developer reads it and knows what's going on. In our everyday coding life, iterators are not good or bad, they're just "what gets the job done".
Probably, yes.
I don't think so.

Andrei at times can be a bit provocative. Iterators are a reasonable concept, and quite fundamental in the sense that bits are. But just like most bits in C++ are not bools, but part of larger types,most iterators should be dealt with at a high level. Andrei is right that the proper level to do so is the range object. But not all ranges are properly exposed as iterator ranges, as the istream_iterator sentinel shows. That's just a hack to create an artificial end iterator. I don't think his ideas will be picked up by implementations, though. C++1x will be as relevant as C99.

C++0x is already making the first steps:
rvalue references solve some problems with treating containers as ranges
ranges have been added to the core library, including range concepts
Transitioning to ranges without losing any iterator functionality (think of all the combinations of iterator categories, const-ness and rvalue-ness) is hard, especially if you try to factor in infinite and mutable ranges.

Isn't Andrei trying to do some hidden marketing for the D language (currently he is working with it)...?
Andrei states that containers are ok, but iterators are ugly, non-intuitive, error-prone and dangerous, hard to implement (well this last one seems to be rather true...) And what do we have in C++... pointers? Aren't they ugly/.../dangerous? But we happily embraced them and live with them.
Which one is more intuitive to write:
for(auto i=foo.begin();i!=foo.end();++i)
bar(*i);
or
for (auto r=foo.all(); !foo.empty(); foo.popFront())
bar(r.front());
Iterators concept can be complemented with ranges and other ideas, but I think that they have their place and won't be replaced.

No, they are not bad, they are very clever idea in fact. However, they are not ideal and there is room for improvements in the concept of iterator.
It solves number of real-life problems with iterators. For instance, it's tedious (also error prone) in many cases to query two separate objects, iterators, from a single containers and then pass them as still two separate objects to an algorithm. Why not to pass a single object around? Even std::pair<iterator, iterator> would make for a crude range which is easier to manipulate - one object, not two. Also, it's a good idea to consider a range is an iterator. That's in fact what Andrei suggests. By the way, some of these problems have been already solved by Boost.Range.
I would expect it happened, but it will not be a revolution, rather evolution.

Sometimes
Probably
Not likely, at least not for many years

I think we should use ranges next to iterators, i.e. we should choose the evolution way, not revolution way.

Like any API or function, if misused can create many problems of identification difficult.
Iterators have used in many projects, but always maintaining the necessary care required according to their characteristics.
Its use should be preceded by a good understanding of their limitations. Iterators can be very useful if user properly.
This questions are related :
Is there any way to check if an iterator is valid?
Should I prefer iterators over const_iterators?

I disagree with both Andrei and Konrad and myself :-)
The most fundamental concept is an interface not an iterator and that is pretty obvious in any work anyone does today (which is all about cross-library, cross-language, cross-compiler, cross-OS, cross-platform, you cross-name it :-)
Neither iterator or range (apart from source-level use) offer anything more than a clean and simple, non intrusive or intrusive, non shared or shared, non unique or unique: pointer ! Clean pointer to typed data is simply put universal and you can make data mutable or immutable and many other things. All interface is is just another level of indirection to it while still being friendly to machine and compiler of all sorts, plus far safer, relegating iterators and range usage to an implementation detail.
To that extent IEnumerable and IQueryable do the half 'right thing' TM but they are clearly inferior in their concepts of iteration and much more to what you can do with STL, retain control and so on and on (but otoh, they have better metadata and hence a better, cleaner model). Point being with interfaces you can build any abstraction you want and satisfy, well probably contraversial but essentially a no-brainer: optimal, and runtime or compile-time neutral data representation and code (heck essential to algorithms and compilers and VMs and what not).
It is even possible to optimise it for 'dynamic'/component systems down to 'runtime' inlining (screw HotSpot VM:-).. To that extent, the advance to 1975 is minimal as evident by a huge interop industry workload (it's everywhere you look, including this site, its use of proprietary and open tech, etc; in computer science idealism, well, this type of interfacing 'work' should not exist should it)..

I think C++ implementors will have their hands full producing full working support for C++0x, without implementing new, non-standard paradigms.

The only argument I can see from that presentation is the inability to define ranges, and the c++0x "Range for statement" proposal seems to eliminate that problem to some extent anyway. maybe it shouldn't be an argument about if iterators should / shouldn't be used at all, but more what situations should / shouldn't they be used for?

Related

What is so great about STL? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I am a Java developer trying to learn C++. I have many times read on the internet (including Stack Overflow) that STL is the best collections library that you can get in any language. (Sorry, I do not have any citations for that)
However after studying some STL, I am really failing to see what makes STL so special. Would you please shed some light on what sets STL apart from the collection libraries of other languages and make it the best collection library?
What is so great about the STL ?
The STL is great in that it was conceived very early and yet succeeded in using C++ generic programming paradigm quite efficiently.
It separated efficiently the data structures: vector, map, ... and the algorithms to operate on them copy, transform, ... taking advantage of templates to do so.
It neatly decoupled concerns and provided generic containers with hooks of customization (Comparator and Allocator template parameters).
The result is very elegant (DRY principle) and very efficient thanks to compiler optimizations so that hand-generated algorithms for a given container are unlikely to do better.
It also means that it is easily extensible: you can create your own container with the interface you wish, as long as it exposes STL-compliant iterators you'll be able to use the STL algorithms with it!
And thanks to the use of traits, you can even apply the algorithms on C-array through plain pointers! Talk about backward compatibility!
However, it could (perhaps) have been better...
What is not so great about the STL ?
It really pisses me off that one always have to use the iterators, I'd really stand for being able to write: std::foreach(myVector, [](int x) { return x+1;}); because face it, most of the times you want to iterate over the whole of the container...
But what's worse is that because of that:
set<int> mySet = /**/;
set<int>::const_iterator it = std::find(mySet.begin(), mySet.end(), 1005); // [1]
set<int>::const_iterator it = mySet.find(1005); // [2]
[1] and [2] are carried out completely differently, resulting in [1] having O(n) complexity while [2] has O(log n) complexity! Here the problem is that the iterators abstract too much.
I don't mean that iterators are not worthy, I just mean that providing an interface exclusively in terms of iterators was a poor choice.
I much prefer myself the idea of views over containers, for example check out what has been done with Boost.MPL. With a view you manipulate your container with a (lazy) layer of transformation. It makes for very efficient structures that allows you to filter out some elements, transform others etc...
Combining views and concept checking ideas would, I think, produce a much better interface for STL algorithms (and solve this find, lower_bound, upper_bound, equal_range issue).
It would also avoid common mistakes of using ill-defined ranges of iterators and the undefined behavior that result of it...
It's not so much that it's "great" or "the best collections library that you can get in *any* language", but it does have a different philosophy to many other languages.
In particular, the standard C++ library uses a generic programming paradigm, rather than an object-oriented paradigm that is common in languages like Java and C#. That is, you have a "generic" definition of what an iterator should be, and then you can implement the function for_each or sort or max_element that takes any class that implements the iterator pattern, without actually having to inherit from some base "Iterator" interface or whatever.
What I love about the STL is how robust it is. It is easy to extend it. Some complain that it's small, missing many common algorithms or iterators. But this is precisely when you see how easy it is to add in the missing components you need. Not only that, but small is beautiful: you have about 60 algorithms, a handful of containers and a handful of iterators; but the functionality is in the order of the product of these. The interfaces of the containers remain small and simple.
Because it's fashion to write small, simple, modular algorithms it gets easier to spot bugs and holes in your components. Yet, at the same time, as simple as the algorithms and iterators are, they're extraordinarily robust: your algorithms will work with many existing and yet-to-be-written iterators and your iterators work with many existing and yet-to-be-written algorithms.
I also love how simple the STL is. You have containers, you have iterators and you have algorithms. That's it (I'm lying here, but this is what it takes to get comfortable with the library). You can mix different algorithms with different iterators with different containers. True, some of these have constraints that forbid them from working with others, but in general there's a lot to play with.
Niklaus Wirth said that a program is algorithms plus data-structures. That's exactly what the STL is about. If Ruby and Python are string superheros, then C++ and the STL are an algorithms-and-containers superhero.
STL's containers are nice, but they're not much different than you'll find in other programming languages. What makes the STL containers useful is that they mesh beautifully with algorithms. The flexibility provided by the standard algorithms is unmatched in other programming languages.
Without the algorithms, the containers are just that. Containers. Nothing special in particular.
Now if you're talking about container libraries for C++ only, it is unlikely you will find libraries as well used and tested as those provided by STL if nothing else because they are standard.
The STL works beautifully with built-in types. A std::array<int, 5> is exactly that -- an array of 5 ints, which consumes 20 bytes on a 32 bit platform.
java.util.Arrays.asList(1, 2, 3, 4, 5), on the other hand, returns a reference to an object containing a reference to an array containing references to Integer objects containing ints. Yes, that's 3 levels of indirection, and I don't dare predict how many bytes that consumes ;)
This is not a direct answer, but as you're coming from Java I'd like to point this out. By comparison to Java equivalents, STL is really fast.
I did find this page, showing some performance comparisons. Generally Java people are very touchy when it comes to performance conversations, and will claim that all kinds of advances are occurring all the time. However similar advances are also occurring in C/C++ compilers.
Keep in mind that STL is actually quite old now, so other, newer libraries may have specific advantages. Given the age, its' popularity is a testament to how good the original design was.
There are four main reasons why I'd say that STL is (still) awesome:
Speed
STL uses C++ templates, which means that the compiler generates code that is specifically tailored to your use of the library. For example, map will automagically generate a new class to implement a map collection of 'key' type to 'value' type. There is no runtime overhead where the library tries to work out how to efficiently store 'key' and 'value' - this is done at compile time. Due to the elegant design some operations on some types will compile down to single assembly instructions (e.g. increment integer-based iterator).
Efficiency
The collections classes have a notion of 'allocators', which you can either provide yourself or use the library-provided ones which allocate only enough storage to store your data. There is no padding nor wastage. Where a built-in type can be stored more efficiently, there are specializations to handle these cases optimally, e.g. vector of bool is handled as a bitfield.
Exensibility
You can use the Containers (collection classes), Algorithms and Functions provided in the STL on any type that is suitable. If your type can be compared, you can put it into a container. If it goes into a container, it can be sorted, searched, compared. If you provide a function like 'bool Predicate(MyType)', it can be filtered, etc.
Elegance
Other libraries/frameworks have to implement the Sort()/Find()/Reverse() methods on each type of collection. STL implements these as separate algorithms that take iterators of whatever collection you are using and operate blindly on that collection. The algorithms don't care whether you're using a Vector, List, Deque, Stack, Bag, Map - they just work.
Well, that is somewhat of a bold claim... perhaps in C++0x when it finally gets a hash map (in the form of std::unordered_map), it can make that claim, but in its current state, well, I don't buy that.
I can tell you, though, some cool things about it, namely that it uses templates rather than inheritance to achieve its level of flexibility and generality. This has both advantages and disadvantages; a disadvantage is that lots of code gets duplicated by the compiler, and any sort of dynamic runtime typing is very hard to achieve; however, a key advantage is that it is incredibly quick. Because each template specialization is really its own separate class generated by the compiler, it can be highly optimized for that class. Additionally, many of the STL algorithms that operate on STL containers have general definitions, but have specializations for special cases that result in incredibly good performance.
STL gives you the pieces.
Languages and their environments are built from smaller component pieces, sometimes via programming language constructs, sometimes via cut-and-paste. Some languages give you a sealed box - Java's collections, for instance. You can do what they allow, but woe betide you if you want to do something exotic with them.
The STL gives you the pieces that the designers used to build its more advanced functionality. Directly exposing the iterators, algorithms, etc. give you an abstract but highly flexible way of recombining core data structures and manipulations in whatever way is suitable for solving your problem. While Java's design probably hits the 90-95% mark for what you need from data structures, the STL's flexibility raises it to maybe 99%, with the iterator abstraction meaning you're not completely on your own for the remaining 1%.
When you combine that with its speed and other extensibility and customizabiltiy features (allocators, traits, etc.), you have a quite excellent package. I don't know that I'd call it the best data structures package, but certainly a very good one.
Warning: percentages totally made up.
Unique because it
focuses on basic algorithms instead of providing ready-to-use solutions to specific application problems.
uses unique C++ features to implement those algorithms.
As for being best... There is a reason why the same approach wasn't (and probably won't) ever followed by any other language, including direct descendants like D.
The standard C++ library's approach to collections via iterators has come in for some constructive criticism recently. Andrei Alexandrescu, a notable C++ expert, has recently begun working on a new version of a language called D, and describes his experiences designing collections support for it in this article.
Personally I find it frustrating that this kind of excellent work is being put into yet another programming language that overlaps hugely with existing languages, and I've told him so! :) I'd like someone of his expertise to turn their hand to producing a collections library for the so-called "modern languages" that are already in widespread use, Java and C#, that has all the capabilities he thinks are required to be world-class: the notion of a forward-iterable range is already ubiquitous, but what about reverse iteration exposed in an efficient way? What about mutable collections? What about integrating all this smoothly with Linq? etc.
Anyway, the point is: don't believe anyone who tells you that the standard C++ way is the holy grail, the best it could possibly be. It's just one way among many, and has at least one obvious drawback: the fact that in all the standard algorithms, a collection is specified by two separate iterators (begin and end) and hence is clumsy to compose operations on.
Obviously C++, C#, and Java can enter as many pissing contests as you want them to. The clue as to why the STL is at least somewhat great is that Java was initially designed and implemented without type-safe containers. Then Sun decided/realised people actually need them in a typed language, and added generics in 1.5.
You can compare the pros and cons of each, but as to which of the three languages has the "greatest" implementation of generic containers - that is solely a pissing contest. Greatest for what? In whose opinion? Each of them has the best libraries that the creators managed to come up with, subject to other constraints imposed by the languages. C++'s idea of generics doesn't work in Java, and type erasure would be sub-standard in typical C++ usage.
The primary thing is, you can use templates to make using containers switch-in/switch-out, without having to resort to the horrendous mess that is Java's interfaces.
If you fail to see what usage the STL has, I recommend buying a book, "The C++ Programming Language" by Bjarne Stroustrup. It pretty much explains everything there is about C++ because he's the dude who created it.

What is the point of STL?

I've been programming c++ for about a year now and when i'm looking about i see lots of references to STL.
Can some one please tell me what it does?
and the advantages and disadvantageous of it?
also what does it give me over the borlands VCL or MFC?
thanks
It's the C++ standard library that gives you all sorts of very useful containers, strings, algorithms to manipulate them with etc.
The term 'STL' is outdated IMHO, what used to be the STL has become a large part of the standard library for C++.
If you are doing any serious C++ development, you will need to be familiar with this library and preferably the boost library. If you are not using it already, you're probably working at the wrong level of abstraction or you're constraining yourself to a small-ish subset of C++.
STL stands for Standard Template Library. This was a library designed mainly by Stepanov and Lee which was then adopted as part of the C++ Standard Library. The term is gradually becoming meaningless, but covers these parts of the Standard Library:
containers (vectors, maps etc.)
iterators
algorithms
If you call yourself a C++ programmer, you should be familiar with all of these concepts, and the Standard Library implementation of them.
The STL is the Standard Template Library. Like any library it's a collection of code that makes your life easier by providing well tested, robust code for you to re-use.
Need a collection (map, list, vector, etc) they're in the STL
Need to operate on a collection (for_each, copy, transform, etc,) they're in the STL
Need to do I/O, there's classes for that.
Advantages
1, You don't have to re-implement standard containers (cus you'll get it wrong anyway)
Read this book by Nicolai M.Josuttis to learn more about the STL, it's the best STL reference book out there.
It provides common useful tools for the programmer! Iterators, algorithms, etc. Why re-invent the wheel?
"advantages and disadvantageous" compared to what? To writing all that code yourself? Is not it obvious? It has great collections and tools to work with them
Wikipedia has a good overview: http://en.wikipedia.org/wiki/Standard_Template_Library
The STL fixes one big deficiency of C++ - the lack of a standard string type. This has cause innumerable headaches as there have been thousands of string implementations that don't work well together.
It stands for standard template library
It is a set of functions and class that are there to save you a lot of work.
They are designed to use templates, which is where you define a function, but with out defining what data type it will work on.
for example, vector more or less lets you have dynamic arrays. when you create an instance of it, you say what type you want it to work for. This can even be your own data type (class).
Its a hard thing to think about, but it is hugely powerful and can save you loads of time.
Get reading up on it now! You want regret it.
It gives you another acronym to toss around at cocktail parties.
Seriously, check the intro docs starting e.g. with the Wikipedia article on STL.
The STL has Iterators. Sure, collections and stuff are useful, but the power iterators is gigantic, and, in my humble opinion, makes the rest pale in comparison.

What questions should an expert in STL be expected to answer, in an interview

I was looking at a job posting recently and one of the requirements was that a person be a 9/10 in their knowledge of STL.
When I judge my skills, to me a 10 is someone that writes advanced books on the subject, such as Jon Skeet (C#), John Resig (JavaScript) or Martin Odersky (Scala).
So, a 9/10 is basically a 10, so I am not certain what would be expected at that level.
An example of some questions would be found at: http://discuss.joelonsoftware.com/default.asp?joel.3.414500.47
Obviously some coding will be needed, but should everything be expected to be memorized, as there is quite a bit in STL.
In some cases Boost libraries extend STL, so should it be expected that I would be using Boost also, as I may sometimes confuse which function came from which of the two libraries.
I am trying to get an idea if I can answer questions that would be expected of a STL expert, though it is odd that being a C++ expert wasn't a requirement.
UPDATE
After reflecting on the answers to my question it appears that what they may be looking for is someone that can see the limits of STL and extend the library, which is something I haven't done. I am used to thinking within the limits of what STL and Boost give me and staying within the lines. I may need to start looking at whether that has been too limiting and see if I can go outside the box. I hope they don't mean a 9 as Google does. :)
Funny -- I don't consider myself a 9/10 in STL (I used to be, but I'm a bit rusty now), and I do fully agree with #joshperry's important terminological distinguo (I've often been on record as berating the abuse of STL to mean "the parts of the C++ standard library that were originally inspired by SGI's STL"!-), yet I consider his example code less than "optimally STL-ish". I mean, for the given task "Put all the integers in a vector to standard out.", why would anyone ever code, as #joshperry suggests,
for(std::vector<int>::iterator it = intVect.begin(); it != intVect.end(); ++i)
std::cout << *it;
rather than the obvious:
std::copy(intVect.begin(), intVect.end(), std::ostream_iterator<int>(std::cout));
or the like?! To me, that would kind of suggest they don't know about std::ostream_iterator -- especially if they're supposed to be showing off their STL knowledge, why wouldn't they flaunt it?-)
At my current employer, to help candidates self-rate about competence in a technology, we provide a helpful guide -- "10: I invented that technology; 9: I wrote THE book about it" and so on down. So, for example, I'd be a 9/10 in Python -- only my colleague and friend Guido can fairly claim a 10/10 there. STL is an interesting case: while Stepanov drove the design, my colleague Matt Austern did the first implementation and wrote "the" book about it, too (this one) -- so I think he'd get to claim, if not a 10, a 9.5. By that standard, I could be somewhere between 7 and 8 if I could take an hour to refresh (custom allocators and traits are always tricky, or at least that's how I recall them!-).
So, if you're probing somebody who claims a 9, grill them over the really hard parts such as custom allocators and traits -- presumably they wouldn't miss a beat on all the containers, algorithms, and special iterators, so don't waste much interview time on those (which would be key if you were probing for a 7 or 7.5). Maybe ask them to give a real-life example where they used custom traits and/or allocators, and code all the details of the implementation as well as a few sample uses.
BTW, if you're the one needing to cram on C++'s standard library at an advanced level, I'm told by knowledgeable and non-rusty friends that Josuttis' book nowadays is even more useful than my friend Matt's (unfortunately, I've never read Josuttis in depth, so I can't confirm or deny that - I do see the book has five stars on Amazon, which is impressive;-).
It is just a dumb requirement for a job. When hiring you want a good great programmer first, specific knowledge second.
It would be reasonable, at this day and age, to expect knowledge/familiarity/etc with the STL. But unless the job is to reimplement the STL, you don't need 9/10. Even if that is the job, you still just need a great programmer that has lots of experience with templates (making not just using).
For example, for all the answers to "output the integers of a vector", probably the exact same code is generated. Only the version that has been templated to handle any container of any items shows a hint of 'great' vs good (just a hint). ie the ability to abstract.
Anyhow, just go for it. Be ready to use the STL to help solve other problems. Nothing more.
(In fact, for most of the interviews I've been in, the requirement was to NOT use the STL. ie - write a function that reverses a string. My first answer is that there is probably something in the std lib that would do that. Then they say, right, of course, but what if you had to write it yourself...)
I should preface this by noting that I think the same criteria should be applied not only to STL (regardless of which definition you prefer for that), but to many other types of things as well.
From my perspective, simply knowing the existing STL components and being able to apply them well probably should not qualify as a 9/10. Rather, I'd consider that level about 7/10. 8/10 is when the person is able to extend the STL by providing new components that follow its philosophy and fit with existing components naturally and easily.
By 9/10, I'd expect to see somebody who can not only provide new components, but is able to improve some of the existing ones, such as Boost::bind. For 10/10, I'd expect to see this go beyond the rather ad hoc, localized improvements of a 9/10, and moving toward looking at a more architectural level, such as using ranges instead of individual iterators. For a concrete example, consider the difference between Boost's ranges and Andrei Alexandrescu's ideas for ranges. Boost's ranges are handy, useful and convenient, but they change what you type, not how you think. Andre's version of ranges is much more all-encompassing -- an architectural solution that changes how you design and think about code, not just how you type it.
Well, you could walk into the interview and say "I noticed that your posting asked for someone knowledgeable in STL but that term is sometimes used to mean: (1) C++ standard library; (2) the library Stepanov designed at HP; (3) the parts of [1] based on [2]; (4) specific vendor implementations of either [1], [2], or [3]; (5) the underlying principles of [2]. As such, the term is highly ambiguous, and must be used with extreme caution. If you meant [1] and insist on abbreviating, "stdlib" is a far better choice."*
Honestly though since it is a library it is somewhat finite and probably not composeable to nauseating infinitum like a language proper. So I would say any question that had them use some of the stdlib algorithms would be effective to see if they knew them well.
With iterators being an integral part of the stdlib I would also maybe ask them to "Put all the integers in a vector to standard out." I would expect something like:
// thanks to onebyone
std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " ");
If they write something like the following they probably aren't very familiar with iterators:
for(int i = 0; i < vec.size(); ++i)
std::cout << vec[i];
Also one interesting thing to look for is if they do using namespace std at the top of their code file. Ask them why, and if they don't say something along the lines of "I use that for short demo code only" or if they put it in a header file, thank them for coming in and send them out the door.
Another aspect of the stdlib is it's heavy use of templates, the person should have a good understanding of basic template programing for type substitution. Maybe ask them to "Write a function that will write all of items of any stdlib container to standard out". I would expect to see something like:
template<typename InputIter>
void Output(InputIter it, InputIter end) {
while(it != end)
std::cout << *it++;
}
These are probably not 9/10 questions but interesting ones I think a 2-3/10 should know.
One 9/10 difficulty I would say is to write a derived iostream properly without using the boost stream base classes. But there is probably quite a difference between using the stdlib and extending it...
*(thanks to nolyc on freenode ##C++ for the quote)
9/10 is quite subjective. I have been asked good questions about STL. These are examples:
When should you use a deque vs a vector (knowledge of how they are internally implemented is helpful)
Recognize STL code that uses invalid references, or can end up using invalid references.
Implement simple operations on different containers, and know where and when to use std::algorithm vs member functions of a container.

C++0X Concepts are gone. Which other features should go too? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
As you may have heard, the last meeting of the C++ standards committee voted to remove concepts from the next C++ standard. Of course, this will affect other features and would seem to throw the standard wide open again. If that is the case, which other features do you think should be stripped away (or added), and why?
Links:
Removal of Concepts -- Danny Kalev (on the decision to remove concepts)
Simplifying the use of Concepts -- Bjarne Stroustrup (on the problems with concepts as they look now)
The Long Pole Gets Longer -- Martin Tasker (on the impact to the schedule for C++0x if concepts have to be fixed)
The C++0x "Remove Concepts" Decision - Stroustrup on the issue on Dr. Dobbs
Trip Report: Exit Concepts, Final ISO C++ Draft in ~18 Months - Herb Sutter
Concepts Get Voted Off The C++0x Island - Jeremy Siek defending the current Concepts spec
What Happened in Frankfurt? - Doug Gregor on C++Next (on the history and removal of Concepts).
Of course, this will affect other
features and would seem to throw the
standard wide open again.
Hardly. They still want to wrap up the standard soon, which is one of the main reasons for removing concepts. Making it "wide open" to unrelated changes would just throw away everything they gained by ditching concepts.
Anyway.... Of the remaining C++0x additions, I can't think of anything else I'd want to remove. I agree with their decision regarding concepts though. Stroustrup's paper really outlined some serious problems, The current specification for concepts would admittedly simplify template error messages, but it would do so by dramatically reducing the usefulness of generic programming -- a price I'm not willing to pay.
When I first read that paper, it scared me, because I assumed it was too late in the process for making serious changes to the spec. Turns out it wasn't, and the committee was willing to take dramatic action.
But apart from this, I think C++0x is in good shape. The remaining new features all look worthwhile.
Of course, there are plenty of existing features I'd love to remove. Primarily the vector<bool> specialization. There are other popular examples of features that didn't work out (the export keyword, exception specifications), but the vector specialization is the only one of them that can't be ignored. As long as we don't try to export templates, it doesn't matter that the keyword exists (and isn't implemented by compilers), and we can just refrain from using exception specs, but every time we need a vector of bools, we're bitten by the stupid premature optimization that slipped into the current standard.
Unfortunately, it seems like they've given up on removing it. (Last I checked, it wasn't even deprecated).
Of course, plenty of old C cruft could be ditched too, but recently, I've discovered that the one change I'd really love to see is...... ditching the Iostreams library. Toss it out, and build a new STL-style I/O library based on generic programming.
The current OOP-styled Iostreams library is ugly, slow, overcomplicated and inflexible. There's too much voodoo involved in defining new streams, too few standard stream types involved, too little flexibility (the problem that made me realize how limited the library is, was that I needed to extract a float from a string. Easy to do with stringstream, but if you need to do it often, you don't want to have to copy the input string every time (as the stringstream does) -- where's the stream that works on an existing iterator range? Or a raw array, even?)
Throw IOstreams out, develop a modern replacement, and C++ will be vastly improved.
And perhaps do something about the string class as well. It works sort of ok'ish as it is now, but really, what's with the huge number of member functions? Most of them would work better, and be more general, as free functions. Too much of the standard library relies specifically on the string class, when it could in principle work with any container, or even an iterator (std::getline, I'm looking at you)
Personally, I want C++ to finally break away from C. No more pre-processor, no more header files. I basically want D, but without all the stuff that D tacks on, using the STL.
None, I think the rest of the draft was great - a large number of very small pieces that can be correctly implemented independently, allowing vendors to evolve toward complete support and allowing users to take a "shopping list" approach.
Quite a different situation with contracts, as they were like a whole new parallel type system and would have been very likely to have led to different compilers ending up with their own backward compatibility problems, very similar to CSS in web browsers.
There are two things I think should be added to C++0x, I've thought of both these myself and then found that others have suggested them before but it doesn't seem like they're going to happen.
1. Defaulting Move Constructors and Move Assignment Operators
Writing a move constructor is a manual and error prone activity, if a member is added it must be added to the move constructor and assignment operators and std::move must be used religiously. That's why I think these functions should be defaultable.
movable(movable&&) = default;
movable& operator=(movable&&) = default;
Edit (2009-10-01): Looks like this is going to happen after all.
2. Override Type Deduction for Expression Templates
Expression templates often define types that should not be used directly, a case in point is the return value of std::vector<bool> operator[](size_type n), if auto or decltype are used on this kind of object unexpected behaviour may ensue.
Therefore a type should be able to say what type it should be deduced to be (or prevent deduction using = delete syntax).
Example for vector addition.
// lazy evaluation of vector addition
template<typename T, class V1, class V2>
class vector_add {
V1& lhs_;
V2& rhs_;
public:
T operator[](size_t n) const
{ return lhs_[n] + rhs_[n]; }
// If used by auto or decltype perform eager creation of vector
std::vector<T> operator auto() const
{
if (lhs_.size() != rhs_.size())
throw std::exception("Vectors aren't same size");
std::vector<T> vec;
vec.reserve(lhs_.size());
for (int i = 0; i < lhs_.size(); ++i)
vec.push_back(lhs_[i] + rhs_[i]);
return vec;
}
To me the problem is not what other features should be stripped away, but how complex will other features be after concepts have been removed. That and how much longer will it take for the rest of the features to be rephrased without concepts.
A lot of features assumed that concepts would be accepted into the language and the wording is expressed in terms of concepts. (I wonder if any proposed feature depends on concepts).
I also wonder how other libraries will evolve (think boost::type_traits) to take the niche left by concepts. Part of what concepts provided can be implemented (even if in a more cumbersome way) in terms of traits applied to the type arguments.
To me, the most important thing that concepts added to the language was an expressive formulation of compilation errors, which is nowadays one of the places where C++ is most criticized.
R.I.P. concepts.
Do whatever you want with concepts, but for god's sake keep threads and atomics, we absolutely need them. Perhaps add thread groups and support for cooperative threads a.k.a. fibers. IMO these are far more important than concepts, because everyone uses/will soon be using threads.
I'd like to remove =delete.
There's already a common and accepted idiom for acheiving the same effect (declare the function in question as private). I think this feature will just generate lots of 'I used =delete to remove a base class function from my derived class, but it can still be called using a base class pointer' questions.
Not to mention confusing people between the (now) two meanings of the delete keyword.
Strip away the pages of error messages on template code!
IIRC concepts should solve a big C++ coder problem: Human readable error messages for the STL. Its bad news that this issue isn't addressed.
The un-named function / lambda function stuff makes me nervous. Function objects are perfectly good and are explicit, thus easier to read and find.
On the other hand I kinda liked concepts, though I certainly would not have used them every day.

Good Idea / Bad Idea Should I Reimplement Most Of C++? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Recently, I've got a dangerous idea into my head after reading this blog post. That idea can be expressed like this:
I don't need most of what the C++ standard library offers. So, why don't I implement a less general, but easier to use version?
As an example, using the STL spits out reams of incomprehensible and mangled compiler errors. But, I don't care about allocators, iterators and the like. So why don't I take a couple of hours and implement an easy to use linked list class, for example?
What I'd like to know from the StackOverflow community is this: what are the dangers, possible disadvantages and possible advantages to "rolling my own" for most of the existing functionality in C++?
Edit: I feel that people have misunderstood me about this idea. The idea was to understand whether I could implement a very small set of STL functionality that is greatly simplified - more as a project to teach me about data structures and the like. I don't propose re-inventing the entire wheel from the ground up, just the part that I need and want to learn about. I suppose what I wanted to figure out is whether the complexity of using the STL warrants the creation of smaller, simpler version of itself.
Re-using boost or similiar.
Most of what I code is for University and we're not allowed to use external libraries. So it's either the C++ standard library, or my own classes.
Objectivity of this question.
This question is not subjective. Nor should it be community Wiki, since it's not a poll. I want concrete arguments that highlight one advantage or one disadvantage that could possibly occur with my approach. Contrary to popular belief, this is not opinion, but based on experience or good logical arguments.
Format.
Please post only one disadvantage or one advantage per answer. This will allow people to evaluate individual ideas instead of all your ideas at once.
And please...
No religious wars. I'm not a fan boy of any language. I use whatever's applicable. For graphics and data compression (what I'm working on at the moment) that seems to be C++. Please constrain your answers to the question or they will be downvoted.
So, why don't I implement a less
general, but easier to use version?
Because you can't. Because whatever else you might say about C++, it is not a simple language, and if you're not already very good at it, your linked list implementation will be buggy.
Honestly, your choice is simple:
Learn C++, or don't use it. Yes, C++ is commonly used for graphics, but Java has OpenGL libraries too. So does C#, Python and virtually every other language. Or C. You don't have to use C++.
But if you do use it, learn it and use it properly.
If you want immutable strings, create your string as const.
And regardless of its underlying implementation, the STL is remarkably simple to use.
C++ compiler errors can be read, but it takes a bit of practice. But more importantly, they are not exclusive to STL code. You'll encounter them no matter what you do, and which libraries you use. So get used to them. And if you're getting used to them anyway, you might as well use STL too.
Apart from that, a few other disadvantages:
No one else will understand your code. If you ask a question on SO about std::vector, or bidirectional iterators, everyone who's reasonably familiar with c++ can answer. If you ask abut My::CustomLinkedList, no one can help you. Which is unfortunate, because rolling your own also means that there will be more bugs to ask for help about.
You're trying to cure the symptom, rather than the cause. The problem is that you don't understand C++. STL is just a symptom of that. Avoiding STL won't magically make your C++ code work better.
The compiler errors. Yes, they're nasty to read, but they're there. A lot of work in the STL has gone into ensuring that wrong use will trigger compiler errors in most cases. In C++ it's very easy to make code that compiles, but doesn't work. Or seems to work. Or works on my computer, but fails mysteriously elsewhere. Your own linked list would almost certainly move more errors to runtime, where they'd go undetected for a while, and be much harder to track down.
And once again, it will be buggy. Trust me. I've seen damn good C++ programmers write a linked list in C++ only to uncover bug after bug, in obscure border cases. And C++ is all border cases. Will your linked list handle exception safety correctly? Will it guarantee that everything is in a consistent state if creating a new node (and thereby calling the object type's constructor) throws an exception? That it won't leak memory, that all the appropriate destructors will be called? Will it be as type-safe? Will it be as performant? There are a lot of headaches to deal with when writing container classes in C++.
You're missing out on one of the most powerful and flexible libraries in existence, in any language. The STL can do a lot that would be a pain even with Java's giant bloated class library. C++ is hard enough already, no need to throw away the few advantages it offers.
I don't care about allocators,
iterators and the like
Allocators can be safely ignored. You pretty much don't even need to know that they exist. Iterators are brilliant though, and figuring them out would save you a lot of headaches. There are only three concepts you need to understand to use STL effectively:
Containers: You already know about these. vectors, linked lists, maps, sets, queues and so on.
Iterators: Abstractions that let you navigate a container (or subsets of a container, or any other sequence of value, in memory, on disk in the form of streams, or computed on the fly).
Algorithms: Common algorithms that work on any pair of iterators. You have sort, for_each, find, copy and many others.
Yes, the STL is small compared to Java's library, but it packs a surprising amount of power when you combine the above 3 concepts. There's a bit of a learning curve, because it is an unusual library. But if you're going to spend more than a day or two with C++, it's worth learning properly.
And no, I'm not following your answer format, because I thought actually giving you a detailed answer would be more helpful. ;)
Edit:
It'd be tempting to say that an advantage of rolling your own is that you'd learn more of the language, and maybe even why the STL is one of its saving graces.. But I'm not really convinced it's true. It might work, but it can backfire too.
As I said above, it's easy to write C++ code that seems to work. And when it stops working, it's easy to rearrange a few things, like the declaration order of variables, or insert a bit of padding in a class, to make it seemingly work again. What would you learn from that? Would that teach you how to write better C++? Perhaps. But most likely, it'd just teach you that "C++ sucks". Would it teach you how to use the STL? Definitely not.
A more useful approach might be utilizing the awesome power of StackOverflow in learning STL the right way. :)
Disadvantage: no one but you will use it.
Advantage: In the process of implementing it you will learn why the Standard Library is a good thing.
Advantages: eating your own dogfood. You get exactly what you do.
Disadvantages: eating your own dogfood. Numerous people, smarter than 99 % of us, have spent years creating STL.
I suggested you learn why:
using the STL spits out reams of
incomprehensible and mangled compiler
errors
first
Disadvantage: you may spend more time debugging your class library than solving whatever university task you have in front of you.
Advantage: you're likely to learn a lot!
There is something you can do about the cryptic compiler STL error messages. STLFilt will help simplify them. From the STLFilt Website:
STLFilt simplifies and/or reformats
long-winded C++ error and warning
messages, with a focus on STL-related
diagnostics (and for MSVC 6, it fully
eliminates C4786 warnings and their
detritus). The result renders many of
even the most cryptic diagnostics
comprehensible.
Have a look here and, if you are using VisualC, also here.
I think you should do it.
I'm sure I'll get flambayed for this, but you know, every C++ programmer around here has drunk a little too much STL coolaid.
The STL is a great library, but I know from first hand experience that if you roll your own, you can:
1) Make it faster than the STL for your particular use cases.
2) You'll write a library with just the interfaces you need.
3) You'll be able to extend all the standard stuff. (I can't tell you how much I've wished std::string had a split() method)...
Everyone is right when they say that it will be a lot of work. Thats true.
But, you will learn a lot. Even if after you write it, you go back to the STL and never use it again, you'll still have learned a lot.
A bit of my experience : Not that long ago I have implemented my own vector-like class because I needed good control on it.
As I needed genericity I made a templated array.
I also wanted to iterate through it not using operator[] but incrementing a pointer like a would do with C, so I don't compute the address of T[i] at each iteration... I added two methods one to return pointer to the allocated memory and another that returns a pointer to the end.
To iterate through an array of integer I had to write something like this :
for(int * p = array.pData(); p != array.pEnd(); ++p){
cout<<*p<<endl;
}
Then when I start to use vectors of vectors I figure out that when it was possible a could allocate a big bloc of memory instead of calling new many times. At this time I add an allocator to the template class.
Only then I notice that I had wrote a perfectly useless clone of std::vector<>.
At least now I know why I use STL...
Disadvantage : IMHO, reimplimenting tested and proven libraries is a rabit hole which is almost garanteed to be more trouble than it's worth.
Another Disadvantage:
If you want to get a C++ job when you're finished with University, most people who would want to recruit you will expect that you are familiar with the Standard C++ library. Not necessarily intimately familiar to the implementation level but certainly familiar with its usage and idioms. If you reimplement the wheel in form of your own library, you'll miss out on that chance. This is nonwithstanding the fact that you will hopefully learn a lot about library design if you roll your own, which might earn you a couple of extra brownie points depending on where you interview.
Disadvantage:
You're introducing a dependency on your own new library. Even if that's sufficient, and your implementation works fine, you still have a dependency. And that can bite you hard with code maintenance. Everyone else (including yourself, in a year's time, or even a month's) will not be familiar with your unique string behavior, special iterators, and so on. Much effort will be needed just to adapt to the new environment before you could ever start refactoring/extending anything.
If you use something like STL, everyone will know it already, it's well understood and documented, and nobody will have to re-learn your custom throwaway environment.
You may be interested in EASTL, a rewrite of the STL Electronic Arts documented a while back. Their design decisions were mostly driven by the specific desires/needs in multiplatform videogame programming. The abstract in the linked article sums it up nicely.
Advantage
If you look into MFC, you'll find that your suggestion already is used in productive code - and has been so for a long time. None of MFC's collection classes uses the STL.
Why don't you take a look at existing C++ libraries. Back when C++ wasn't quite as mature, people often wrote their own libraries. Have a look at Symbian (pretty horrible though), Qt and WxWidgets (if memory serves me) have basic collections and stuff, and there are probably many others.
My opinion is that the complexity of STL derives from the complexity of the C++ language, and there's little you can do to improve on STL (aside from using a more sensible naming convention). I recommend simply switching to some other language if you can, or just deal with it.
Disadvantage : You're university course is probably laid out like this for a reason. The fact that you are irritated enough by it (sarcasm not intended), may indicate you are not getting the paridigm, and will benefit a lot when you have a paradigm shift.
As an example, using the STL spits out
reams of incomprehensible and mangled
compiler errors
The reason for this is essentially C++ templates. If you use templates (as STL does) you will get reams of incomprehensible error messages. So if you implement your own template based collection classes you will not be in any better spot.
You could make non template based containers and store everything as void pointers or some base class e.g. But you would lose compile time type checks and C++ sucks as a dynamic language. It is not as safe to do this as it would be in e.g. Objective-C, Python or Java. One of the reasons being that C++ does not have a root class for all classes to all introspection on all objects and some basic error handling at runtime. Instead your app would likely crash and burn if you were wrong about the type and you would not be given any clues to what went wrong.
Disadvantage: reimplementing all of that well (that is, at a high level of quality) will certainly take a number of great developers a few years.
what are the dangers, possible disadvantages and possible advantages to "rolling my own" for most of the existing functionality in C++?
Can you afford and possibly justify the amount of effort/time/money spent behind reinventing the wheel?
Re-using boost or similiar.
Rather strange that you cannot use Boost. IIRC, chunks of contribution come in from people related to/working in universities (think Jakko Jarvi). The upsides of using Boost are far too many to list here.
On not 'reinventing the wheel'
Disadvantage: While you learn a lot, you also set yourself back, when you come to think of what your real project objectives are.
Advantage: Maintenance is easier for the folks who are going to inherit this.
STL is very complex because it needs to be for a general purpose library.
Reasons why STL is the way it is:
Based on interators so standard algorithms only need a single implementation for different types of containers.
Designed to behave properly in the face of Exceptions.
Designed to be 'thread' safe in multi threaded applications.
In a lot of applications however you really have enough with the following:
string class
hash table for O(1) lookups
vector/array with sort / and binary search for sorted collections
If you know that:
Your classes do not throw exceptions on construction or assignment.
Your code is single threaded.
You will not use the more complex STL algorithms.
Then you can probably write your own faster code that uses less memory and produces simpler compile/runtime errors.
Some examples for faster/easier without the STL:
Copy-on-Write string with reference counted string buffer. (Do not do this in a multi-threaded environment since you would need to lock on the reference count access.)
Use a good hash table instead of the std::set and std::map.
'Java' style iterators that can be passed around as a single object
Iterator type that does not need to know the type of the container (For better compile time decoupling of code)
A string class with more utility functions
Configurable bounds checking in your vector containers. (So not [] or .at but the same method with a compile or runtime flag for going from 'safe' to 'fast' mode)
Containers designed to work with pointers to objects that will delete their content.
It looks like you updated the question so now there are really two questions:
What should I do if I think the std:: library is too complex for my needs?
Design your own classes that internally use relevant std:: library features to do the "heavy lifting" for you. That way you have less to get wrong, and you still get to invent your own coding interface.
What should I do if I want to learn how data structures work?
Design your own set of data structure classes from the ground up. Then try to figure out why the standard ones are better.