Documente Academic
Documente Profesional
Documente Cultură
Andrei Alexandrescu
c 2009 Andrei Alexandrescu 1 / 52
This Talk
• The STL
• Iterators
• Range-based design
• Conclusions
c 2009 Andrei Alexandrescu 2 / 52
What is the STL?
c 2009 Andrei Alexandrescu 3 / 52
Yeah, what is the STL?
c 2009 Andrei Alexandrescu 4 / 52
Yeah, what is the STL?
c 2009 Andrei Alexandrescu 4 / 52
Yeah, what is the STL?
c 2009 Andrei Alexandrescu 4 / 52
Yeah, what is the STL?
c 2009 Andrei Alexandrescu 4 / 52
Yeah, what is the STL?
c 2009 Andrei Alexandrescu 4 / 52
What the STL is
c 2009 Andrei Alexandrescu 5 / 52
STL is nonintuitive
c 2009 Andrei Alexandrescu 6 / 52
STL is nonintuitive
c 2009 Andrei Alexandrescu 6 / 52
Nonintuitive
c 2009 Andrei Alexandrescu 7 / 52
Nonintuitive
c 2009 Andrei Alexandrescu 8 / 52
Fundamental vs. Incidental in STL
c 2009 Andrei Alexandrescu 8 / 52
Fundamental vs. Incidental in STL
c 2009 Andrei Alexandrescu 8 / 52
Fundamental vs. Incidental in STL
c 2009 Andrei Alexandrescu 8 / 52
Fundamental vs. Incidental in STL
c 2009 Andrei Alexandrescu 8 / 52
STL: The Good
• General
• Efficient
• Reasonably extensible
c 2009 Andrei Alexandrescu 9 / 52
STL: The Bad
c 2009 Andrei Alexandrescu 10 / 52
STL: The Ugly
c 2009 Andrei Alexandrescu 11 / 52
STL: The Ugly
• Iterators suck
◦ Verbose
◦ Unsafe
◦ Poor Interface
c 2009 Andrei Alexandrescu 11 / 52
What’s the Deal with Iterators?
c 2009 Andrei Alexandrescu 12 / 52
Iterators Rock
c 2009 Andrei Alexandrescu 13 / 52
Warning Sign #1
c 2009 Andrei Alexandrescu 14 / 52
Warning Sign #1
c 2009 Andrei Alexandrescu 14 / 52
Warning Sign #2
#include <stdio.h>
int main() {
int c;
while ((c = getchar()) != EOF)
putchar(c);
return errno != 0;
}
c 2009 Andrei Alexandrescu 15 / 52
Warning Sign #2
Fast forward 20 years, and. . .
#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
using namespace std;
int main() {
copy(istream_iterator<string>(cin),
istream_iterator<string>(),
ostream_iterator<string>(cout,"\n"));
}
c 2009 Andrei Alexandrescu 16 / 52
(forgot the try/catch around main)
c 2009 Andrei Alexandrescu 17 / 52
Something, somewhere, went terribly wrong.
c 2009 Andrei Alexandrescu 18 / 52
Warning Sign #3
c 2009 Andrei Alexandrescu 19 / 52
Warning Sign #4
c 2009 Andrei Alexandrescu 20 / 52
Final nail in the coffin
c 2009 Andrei Alexandrescu 22 / 52
Enter Ranges
c 2009 Andrei Alexandrescu 23 / 52
They made an interesting step in a good direction.
c 2009 Andrei Alexandrescu 24 / 52
Things must be taken much further.
c 2009 Andrei Alexandrescu 25 / 52
Look, Ma, no iterators!
c 2009 Andrei Alexandrescu 26 / 52
Defining Ranges
c 2009 Andrei Alexandrescu 27 / 52
Input/Forward Ranges
c 2009 Andrei Alexandrescu 28 / 52
Verifiable?
c 2009 Andrei Alexandrescu 30 / 52
Design Question
c 2009 Andrei Alexandrescu 31 / 52
Design Question
c 2009 Andrei Alexandrescu 31 / 52
Design Question
c 2009 Andrei Alexandrescu 31 / 52
Find
// Using ranges
template<class R, class T>
R find(R r, T value) {
for (; !r.empty(); r.popFront())
if (value == r.front()) break;
return r;
}
...
auto r = find(v.all(), value);
if (!r.empty()) ...
c 2009 Andrei Alexandrescu 32 / 52
Elegant Specification
c 2009 Andrei Alexandrescu 33 / 52
Bidirectional Ranges
c 2009 Andrei Alexandrescu 34 / 52
Reverse Iteration
c 2009 Andrei Alexandrescu 35 / 52
How about find_end?
c 2009 Andrei Alexandrescu 36 / 52
find_end with iterators sucks
c 2009 Andrei Alexandrescu 37 / 52
More composition opportunities
c 2009 Andrei Alexandrescu 38 / 52
How about three-iterators functions?
c 2009 Andrei Alexandrescu 39 / 52
“Where there’s hardship, there’s opportunity.”
– I. Meade Etop
c 2009 Andrei Alexandrescu 40 / 52
3-legged algos ⇒ mixed-range algos
vector<float> v;
list<int> s;
deque<double> d;
copy(chain(v, s), d);
c 2009 Andrei Alexandrescu 41 / 52
3-legged algos ⇒ mixed-range algos
• You can take a vector and a deque and put the smallest
elements of both in the array!
vector<double> v;
deque<double> d;
partial_sort(v, d);
c 2009 Andrei Alexandrescu 42 / 52
But wait, there’s more
c 2009 Andrei Alexandrescu 43 / 52
But wait, there’s even more
vector<double> vd;
vector<string> vs;
// sort the two in lockstep
sort(zip(vs, vd));
c 2009 Andrei Alexandrescu 44 / 52
Output ranges
struct OutRange {
typedef Typelist<int, double, string> Types;
void put(int);
void put(double);
void put(string);
}
c 2009 Andrei Alexandrescu 45 / 52
Back to copying stdin to stdout
#include <...>
int main() {
copy(istream_range<string>(cin),
ostream_range(cout, "\n"));
}
1
slide limitations notwithstanding
c 2009 Andrei Alexandrescu 46 / 52
Infinite ranges
c 2009 Andrei Alexandrescu 47 / 52
has_size
c 2009 Andrei Alexandrescu 48 / 52
A Twist
• Easy composition
c 2009 Andrei Alexandrescu 50 / 52
Announcement
c 2009 Andrei Alexandrescu 51 / 52
Andrei Alexandrescu, Ph %@! D
c 2009 Andrei Alexandrescu 52 / 52