Effective STL Terms 36

zhaozj2021-02-11  192

Terms 36: Understand the correct implementation of COPY_IF

STL has a lot of interesting places, one of which is the algorithm of 11 names "COPY":

CopyCopy_BackwardReplace_copyreverse_copyreplace_copy_ifunique_copyremove_copyrotate_copyremove_copy_ifpartial_sort_copyunintialized_copy

But no one is copy_if. This means you can write_copy_if, you can write_copy_if, you can copy_backward or reverse_copy, but if you just simply want to copy an interval element to meet a decicate element, you can only do it.

For example, suppose you have a function to determine if a widget is defective:

Bool Isdefective (Const Widget & W);

And you want to write all the defective Widgets in a Vector to CERR. If there is a copy_if, you can do this simply:

Vector Widgets;

...

COPY_IF (Widgets.begin (), widgets.end (), // This is unable to compile:

ostream_iterator (CERR, "/ N"), // STL does not have a COPYIF

isdefective;

It is ironic, copy_if is part of the initial HP STL, HP STL forms a STL basis, and STL is now part of the standard C library. Some quirks will make history, and when screening some size is easy to manage from the HP STL, copy_if is a thing that is abandoned in the splicing room.

In "The C Programming Language" [7], Stroustrup emphasizes that writing_if is slightly, he is right, but that doesn't mean that the correct trivial matter is simple. For example, there is a reasonable look at COPY_IF, many people (including me) have realized:

Template

TypeName Outputiterator, // COPY_IF implementation

Typename Predicate>

Outputiterator COPY_IF (InputItemrator Begin,

Inputiterator End,

Outputiterator Destbegin, PRedicate P)

{

Return Remove_copy_IF (Begin, End, Destbegin, Not1 (P));

}

This method is based on this point - although STL does not let you say "copying each judgment True", but it does let you say "copy except for each thing that is not True". To implement COPY_IF, it seems that we need to do it just adding a NOT1 in front of the judgment we want to pass to COPY_IF, and then judge the result to remove_copy_if, the result is the code above.

If the above reasons are valid, we can use this method to write a defective Widget:

Copy_if (Widgets.begin (), Widgets.end (), // Well-Intentioned Code

Ostream_iterator (CERR, "/ N"), // That Will Not CompilesDefective;

Your STL platform will host this code because it tries to apply NOT1 for Isdefective application (this application appears inside the COPY_IF). As the clause 41 is trying to be clear, NOT1 cannot be directly applied to a function pointer, and the function pointer must be transmitted to PTR_FUN. To call this COPY_IF implementation, you must pass not only a function object, but also an adaptive function object. This is simple enough, but people who want to be a STL algorithm user should not have to do this. Standard STL algorithm never requires their imitation functionality, and copy_if should not be required. The implementation above is good, but not good enough.

This is the correct implementation of COPY_IF:

Template

TypeName OutputIutiterator, / / ​​correctly

Typename Predicate>

Outputiterator COPY_IF (InputItemrator Begin,

Inputiterator End,

Outputiterator Desbegin,

PRedicate P) {

While (begin! = End) {

IF (p (* begin) * destbegin = * begin

Begin;

}

Return destbegin;

}

Tell you how Copy_IF is useful, plus the new STL programmer tend to hope that the fact that it should exist, so good practice is to put the copy_if - the right one! - Place in your local STL related tool library, and just use it as appropriate.

转载请注明原文地址:https://www.9cbs.com/read-4772.html

New Post(0)