Online Book Reader

Home Category

Professional C__ - Marc Gregoire [239]

By Root 1085 0

size_t cnt = 0;

cout << "Enter number of elements you want to copy: ";

cin >> cnt;

cnt = min(cnt, vec1.size());

vec2.resize(cnt);

copy_n(vec1.cbegin(), cnt, vec2.begin());

for_each(vec2.cbegin(), vec2.cend(), [](int i){cout << i << " ";});

Code snippet from ModifyingAlgorithms\copy_n.cpp

The last copy-related algorithm added by C++11 is called partition_copy(), which copies elements from the source to two different destinations. The specific destination for each element is selected based on the result of a predicate, either true or false. The returned value of partition_copy() is a pair of iterators: one iterator referring to one-past-the-last-copied element in the first destination range, and one iterator referring to one-past-the-last-copied element in the second destination range. These returned iterators can be used in combination with erase() to remove excess elements from the two destination ranges, just as with the copy_if() example earlier. The following example asks the user to enter a number of integers, which are then partitioned into two destination vectors; one for the even numbers and one for the odd numbers:

// The populateContainer() function is identical to the one shown earlier

// for comparison algorithms, so it is omitted here.

vector vec1, vecOdd, vecEven;

populateContainer(vec1);

vecOdd.resize(vec1.size());

vecEven.resize(vec1.size());

auto pairIters = partition_copy(vec1.cbegin(), vec1.cend(),

vecEven.begin(), vecOdd.begin(),

[](int i){return i%2==0;});

vecEven.erase(pairIters.first, vecEven.end());

vecOdd.erase(pairIters.second, vecOdd.end());

cout << "Even numbers: ";

for_each(vecEven.cbegin(), vecEven.cend(), [](int i){cout << i << " ";});

cout << endl << "Odd numbers: ";

for_each(vecOdd.cbegin(), vecOdd.cend(), [](int i){cout << i << " ";});

Code snippet from ModifyingAlgorithms\partition_copy.cpp

The output can be as follows:

Enter a number (0 to quit): 11

Enter a number (0 to quit): 22

Enter a number (0 to quit): 33

Enter a number (0 to quit): 44

Enter a number (0 to quit): 0

Even numbers: 22 44

Odd numbers: 11 33

Note that the last few examples used the for_each() algorithm to print elements of a container. As seen in other examples, you can also print the elements using a C++11 range-based for loop. For example, instead of writing the following:

for_each(vecOdd.cbegin(), vecOdd.cend(), [](int i){cout << i << " ";});

You can write:

for (auto& i : vecOdd)

cout << i << " ";

move

C++11 adds two move related algorithms: move() and move_backward(). They both use the move semantics introduced in C++11 and discussed in Chapter 9. You have to provide a move assignment operator in your element classes if you want to use these new algorithms on containers with elements of your own types, as demonstrated in the following example. Consult Chapter 9 for details on implementing move assignment operators and the use of std::move(). The MyClass example defines a move assignment operator. The main() function creates a vector with three MyClass objects and then moves those elements from vecSrc to vecDst. Note that the code includes two different uses of move(). The move() function accepting a single argument converts an lvalue into an rvalue (Chapter 9), while move() accepting three arguments is the STL move() algorithm to move elements between containers.

class MyClass

{

public:

MyClass() {}

MyClass(const string& str) : mStr(str) {}

// Move assignment operator

MyClass& operator=(MyClass&& rhs) {

if (this == &rhs)

return *this;

mStr = std::move(rhs.mStr);

cout << "Move operator= (mStr=" << mStr << ")" << endl;

return *this;

}

string getString() const {return mStr;}

protected:

string mStr;

};

int main()

{

vector vecSrc = {MyClass("a"), MyClass("b"), MyClass("c")};

vector vecDst(vecSrc.size());

move(vecSrc.begin(), vecSrc.end(), vecDst.begin());

for (auto& c : vecDst) cout << c.getString() << " ";

return 0;

}

Code snippet from ModifyingAlgorithms\move.cpp

The output is as follows:

Move operator= (mStr=a)

Move operator=

Return Main Page Previous Page Next Page

®Online Book Reader