Show Lecture.Vector as a slide show.
CS253 Vector
Old School
- Old-style C arrays still work just fine.
- They have no methods.
- They are NOT stretchy.
int a[10];
for (int i=0; i<10; i++)
a[i] = i*i;
for (int i=0; i<10; i++)
cout << a[i] << ' ';
0 1 4 9 16 25 36 49 64 81
int a[10];
for (int i=0; i<10; i++)
a[i] = i*i;
for (auto val : a)
cout << val << ' ';
0 1 4 9 16 25 36 49 64 81
vector<int> v;
for (int i=0; i<10; i++)
v.push_back(i*i*i);
for (size_t i=0; i<v.size(); i++)
cout << v[i] << ' ';
0 1 8 27 64 125 216 343 512 729
vector<int> v(10);
for (int i=0; i<10; i++)
v[i] = i*i*i;
for (auto val : v)
cout << val << ' ';
0 1 8 27 64 125 216 343 512 729
Useful vector methods
For a vector named v
:
v.size()
: returns the current length, as a size_t
v.push_back()
: add an element to the end
v.pop_back()
: remove an element from the end
v.erase()
: remove an element from anywhere
v[i]
or v.at(i)
: indexing
- and many more methods
vector constructors
Vectors have several constructors, including:
// default size of zero elements
vector<float> a;
// initialize with these values
vector<float> b = {1.2, 3.4};
// resize to this many zeroes
vector<float> c(170);
if (a != b)
cout << "unequal\n";
unequal
You can have a vector of nearly any type, but you have to pick one.
vector<string> some_strings;
vector<double> some_doubles(42);
vector<bool> some_bools = {true, false};
cout << some_strings.size() << '\n';
cout << some_doubles.size() << '\n';
cout << some_bools.size() << '\n';
0
42
2
vector oops;
c.cc:1: error: class template argument deduction failed:
Stretchy under certain circumstances
Sure, vector is stretchy at certain points.
It’s not magic. The vector grows when:
vector<string> spices;
cout << spices.size() << endl;
spices[0] = "Posh"; // BAD!
0
SIGSEGV: Segmentation fault
Stretchy under certain circumstances
- You can only access
[
n ]
if there are at least
n +1 elements already in the vector.
- vector::push_back() guarantees that there’s enough space
for another element, and then adds the element at the end (back).
vector<string> spices = {"Posh", "Sporty"};
cout << spices.size() << '\n';
spices.push_back("Scary");
cout << spices.size() << '\n';
spices.push_back("Ginger");
spices.push_back("Baby");
cout << spices.size() << '\n';
for (auto s : spices)
cout << s << ' ';
2
3
5
Posh Sporty Scary Ginger Baby
Stretchy under certain circumstances
- If you know the initial size, you can say so in the ctor. This
will initialize the vector to that many empty (default-constructed)
entries.
vector<string> spices(5);
spices[0] = "Posh";
spices[1] = "Sporty";
spices[2] = "Scary";
cout << spices.size() << '\n';
spices[3] = "Ginger";
spices[4] = "Baby";
cout << spices.size() << '\n';
for (auto s : spices)
cout << s << ' ';
5
5
Posh Sporty Scary Ginger Baby
- Don’t combine this with
.push_back()
, though.
Stretchy under certain circumstances
- Of course, if you know the initial data, just say so without counting.
vector<string> spices = { "Posh", "Sporty", "Scary",
"Ginger", "Baby" };
cout << spices.size() << '\n';
for (auto s : spices)
cout << s << ' ';
5
Posh Sporty Scary Ginger Baby
CTAD
The C++17 feature
Class Template Argument Deduction, or CTAD,
allows the omission of the type in some cases when a container is being
initialized:
vector winkies = {11,22,33}; // no <int>!
for (auto v : winkies)
cout << v << ' ';
11 22 33
vector quadlings{'G', 'l', 'i', 'n', 'd', 'a'};
for (auto v : quadlings)
cout << v << ' ';
G l i n d a
CTAD requires initialization
CTAD deduces the type from the initialization, so
you’ve got to have initialization for this to work. You can’t
have a vector of type whatever-you-put-into-it-later:
vector<int> munchkins;
munchkins.push_back(1900);
cout << munchkins[0];
1900
vector gillikins;
gillikins.push_back(1904);
cout << gillikins[0];
c.cc:1: error: class template argument deduction failed:
CTAD with other types
CTAD works with all standard C++ containers, and other types that we
haven’t discussed, yet:
set<const char *> s = {"Every", "Good", "Boy", "Does", "Fine"};
list<double> l{440.0, 880.0};
pair<set<const char *>, list<double>> p(s,l);
cout << p.first.size() << ' ' << p.second.size();
5 2
set s = {"Every", "Good", "Boy", "Does", "Fine"};
list l{440.0, 880.0};
pair p(s,l);
cout << p.first.size() << ' ' << p.second.size();
5 2