Among other things, the generic algorithms in the standard library provide a
Here’s an example of how to use the copy algorithm:
//: C06:CopyInts.cpp
// Copies ints without an explicit loop
#include
#include
#include
using namespace std;
int main() {
int a[] = {10, 20, 30};
const size_t SIZE = sizeof a / sizeof a[0];
int b[SIZE];
copy(a, a + SIZE, b);
for (int i = 0; i < SIZE; ++i)
assert(a[i] == b[i]);
} ///:~.
The copy algorithm’s first two parameters represent the
The copy( ) algorithm wouldn’t be very exciting if it could only process integers. It can in fact copy any sequence. The following example copies string objects.
//: C06:CopyStrings.cpp
// Copies strings
#include
#include
#include
#include
using namespace std;
int main() {
string a[] = {"read", "my", "lips"};
const size_t SIZE = sizeof a / sizeof a[0];
string b[SIZE];
copy(a, a + SIZE, b);
assert(equal(a, a + SIZE, b));
} ///:~.
This example introduces another algorithm, equal( ), which returns true only if each element in the first sequence is equal (using its operator==( )) to the corresponding element in the second sequence. This example traverses each sequence twice, once for the copy, and once for the comparison, without a single explicit loop!.
Generic algorithms achieve this flexibility because they are function templates, of course. If you guessed that the implementation of copy( ) looked something like the following, you’d be "almost" right.
template
void copy(T* begin, T* end, T* dest) {
while (begin != end)
*dest++ = *begin++;
}.
We say "almost," because copy( ) can actually process sequences delimited by anything that acts like a pointer, such as an iterator. In this way, copy( ) can duplicate a vector, as in the following example.
//: C06:CopyVector.cpp
// Copies the contents of a vector
#include
#include
#include
#include
using namespace std;
int main() {
int a[] = {10, 20, 30};
const size_t SIZE = sizeof a / sizeof a[0];
vector
vector
copy(v1.begin(), v1.end(), v2.begin());
assert(equal(v1.begin(), v1.end(), v2.begin()));
} ///:~.
The first vector, v1, is initialized from the sequence of integers in the array a. The definition of the vector v2 uses a different vector constructor that makes room for SIZE elements, initialized to zero (the default value for integers).
As with the array example earlier, it’s important that v2 have enough space to receive a copy of the contents of v1. For convenience, a special library function, back_inserter( ), returns a special type of iterator that
//: C06:InsertVector.cpp
// Appends the contents of a vector to another
#include
#include
#include
#include
#include
using namespace std;
int main() {
int a[] = {10, 20, 30};
const size_t SIZE = sizeof a / sizeof a[0];
vector
vector
copy(v1.begin(), v1.end(), back_inserter(v2));
assert(equal(v1.begin(), v1.end(), v2.begin()));
} ///:~
The back_inserter( ) function is defined in the