Show Lecture.CopyIf as a slide show.
CS253 Copy If
Introduction
copy_if()
is like copy()
, except that it doesn’t copy everything.
- Instead it takes a predicate that determines whether or not
to copy a given element.
- A predicate is a function that returns
bool
.
copy_if()
takes three iterators and a predicate:
copy_if(source-begin, source-end, dest-begin, predicate)
- Why isn’t there a dest-end?
- It isn’t needed. source-begin and source-end say how much to copy.
First attempt
Let’s ensure that we know how to use copy()
before moving on to copy_if()
:
string foo = "This is serious—I have to ration my Diet Mountain Dew!";
cout << foo << "\n";
string bar;
copy(foo.begin(), foo.end(), bar.begin());
cout << bar << "\n";
SIGSEGV: Segmentation fault
Why did that fail? No space allocated in bar
.
Second attempt
string foo = "This is serious—I have to ration my Diet Mountain Dew!";
cout << foo << "\n";
string bar(foo.size(), 'X');
copy(foo.begin(), foo.end(), bar.begin());
cout << bar << "\n";
This is serious—I have to ration my Diet Mountain Dew!
This is serious—I have to ration my Diet Mountain Dew!
- There—we allocated enough space in
bar
:
- The
string(
size_t, char)
constructor filled bar
with the appropriate number of 'X'
characters.
Third attempt
string foo = "This is serious—I have to ration my Diet Mountain Dew!";
cout << foo << "\n";
string bar(foo.size(), 'X');
// Don’t copy vowels:
copy_if(foo.begin(), foo.end(), bar.begin(),
[](char c){return "aeiouyAEIOUY"s.find(c)==string::npos;} );
cout << bar << "\n";
This is serious—I have to ration my Diet Mountain Dew!
Ths s srs— hv t rtn m Dt Mntn Dw!XXXXXXXXXXXXXXXXXXXXX
- Hooray,
copy_if()
worked!
- Hey, what’s with those X’s?
bar.size()
is unchanged.
Fourth attempt
string foo = "This is serious—I have to ration my Diet Mountain Dew!";
cout << foo << "\n";
string bar(foo.size(), 'X');
// Don’t copy vowels:
auto it = copy_if(foo.begin(), foo.end(), bar.begin(),
[](char c){return "aeiouyAEIOUY"s.find(c)==string::npos;} );
// Make bar the correct size:
bar.resize(it-bar.begin());
cout << bar << "\n";
This is serious—I have to ration my Diet Mountain Dew!
Ths s srs— hv t rtn m Dt Mntn Dw!
We resized bar to the correct size.
In-place
string foo = "This is serious—I have to ration my Diet Mountain Dew!";
cout << foo << "\n";
auto it = copy_if(foo.begin(), foo.end(), foo.begin(),
[](char c){return "aeiouyAEIOUY"s.find(c)==string::npos;} );
// Make foo the correct size:
foo.resize(it-foo.begin());
cout << foo << "\n";
This is serious—I have to ration my Diet Mountain Dew!
Ths s srs— hv t rtn m Dt Mntn Dw!
We can copy from & to the same location.