官术网_书友最值得收藏!

Write-only range algorithms

We began this chapter looking at algorithms such as std::find that march through a range reading its elements in order without modification. You might be surprised to learn that the inverse operation also makes sense: there is a family of standard algorithms that march through a range modifying each element without reading it!

std::fill(a,b,v) does what its name implies: fill each element of the given range [a,b) with a copy of the provided value v.

std::iota(a,b,v) is slightly more interesting: it fills the elements of the given range with copies of ++v. That is, std::iota(a,b,42) will set a[0] equal to 42, a[1] equal to 43, a[2] equal to 44, and so on all the way up to b. This algorithm's funny name comes from the APL programming language, where a function named ι (that's the Greek letter iota) performed this operation. Another funny thing about this algorithm is that, for whatever reason, its definition is found in the standard <numeric> header instead of in <algorithm>. It's just an oddball that way.

std::generate(a,b,g) is even more interesting: it fills the elements of the given range with the successive results of g(), whatever it is:

    template<class FwdIt, class T>
void fill(FwdIt first, FwdIt last, T value) {
while (first != last) {
*first = value;
++first;
}
}

template<class FwdIt, class T>
void iota(FwdIt first, FwdIt last, T value) {
while (first != last) {
*first = value;
++value;
++first;
}
}

template<class FwdIt, class G>
void generate(FwdIt first, FwdIt last, G generator) {
while (first != last) {
*first = generator();
++first;
}
}

Here's an example of using each of these standard algorithms to fill a vector of strings with different contents. Test your understanding: do you understand why each call produces the output that it does? The example I picked for std::iota is particularly interesting (yet unlikely to be helpful in real-world code):

    std::vector<std::string> v(4);

std::fill(v.begin(), v.end(), "hello");
assert(v[0] == "hello");
assert(v[1] == "hello");
assert(v[2] == "hello");
assert(v[3] == "hello");

std::iota(v.begin(), v.end(), "hello");
assert(v[0] == "hello");
assert(v[1] == "ello");
assert(v[2] == "llo");
assert(v[3] == "lo");

std::generate(v.begin(), v.end(), [i=0]() mutable {
return ++i % 2 ? "hello" : "world";
});
assert(v[0] == "hello");
assert(v[1] == "world");
assert(v[2] == "hello");
assert(v[3] == "world");
主站蜘蛛池模板: 中方县| 桃源县| 呼伦贝尔市| 信阳市| 革吉县| 府谷县| 涡阳县| 天峻县| 温州市| 萨迦县| 武邑县| 静安区| 嘉兴市| 肥西县| 石屏县| 永春县| 潢川县| 临朐县| 汉川市| 无锡市| 庆云县| 开鲁县| 斗六市| 喀喇沁旗| 项城市| 杨浦区| 肃南| 金阳县| 大连市| 老河口市| 府谷县| 临清市| 积石山| 无为县| 灵台县| 塔河县| 石柱| 阿城市| 江门市| 九江县| 安陆市|