この記事が公開される頃にはVisual Studio 2010のパッケージ販売が始まっているでしょうか。MSDN Subscriptionでは先行提供されていますし、各言語のExpress版が公開されていますから、初物(?)の好きなミナサマは早速遊んでいらっしゃることと思います。
C++屋の僕にとって一番嬉しかったのはVisual C++ 2010(vc10)でC++0xに(完全ではないにせよ)準拠してくれたこと。特にlambda式にはドキドキさせられました。lambda式のサポートにより、より明快でコンパクトな表現が可能になりました。正規表現(regex)や配列(array)、賢いポインタ(shared_ptr/weak_ptr)などなど、サポートが待ち望まれていたクラス群が追加されています。本稿ではvc10で新たに追加されたSTLアルゴリズムを一気に紹介します。
以降、プロトタイプと説明/サンプルが淡々と続きます。適宜リファレンスとしてお使いください。
none_of, any_of, all_of
template <class InputIterator, class Predicate> bool none_of(InputIterator first, InputIterator last, Predicate pred); template <class InputIterator, class Predicate> bool any_of(InputIterator first, InputIterator last, Predicate pred); template <class InputIterator, class Predicate> bool all_of(InputIterator first, InputIterator last, Predicate pred);
ふたつのイテレータfirst、lastを始点と終点とする範囲[first,last)が指す要素のうち、与えた条件を満たす要素の数が「0か」「1以上か」「すべてか」を判定するのがnone_of、any_of、all_ofです。
#include <iostream>
#include <functional>
#include <array>
#include <vector>
#include <iterator>
#include <cassert>
#include <algorithm>
#include <numeric>
using namespace std;
int main() {
function<bool(int)> u_positive = [](int n) { return n > 0; };
function<bool(int)> u_negative = [](int n) { return n < 0; };
function<bool(int)> u_zero = [](int n) { return n == 0; };
function<bool(int)> u_even = [](int n) { return n % 2 == 0; };
function<bool(int)> u_odd = [](int n) { return n % 2 != 0; };
bool result;
typedef array<int,5> ia5;
ia5 c = { 2, 3, 4, 5, 6 };
// none_of
result = none_of(c.begin(), c.end(), u_zero); // 0は一個もないよね
assert(result);
result = none_of(c.begin(), c.begin(), u_zero); // 空集合なら当然true
assert(result);
// 従来こう書いてた
result = find_if(c.begin(), c.end(), u_zero) == c.end();
assert(result);
// any_of
result = any_of(c.begin(), c.end(), u_odd); // 偶数は少なくとも一個ある
assert(result);
result = any_of(c.begin(), c.begin(), u_odd); // 空集合なら当然false
assert(!result);
result = any_of(c.begin(), c.end(), u_negative); // 負数は一個もないからfalse
assert(!result);
// 従来こう書いてた
result = find_if(c.begin(), c.end(), u_odd) != c.end();
assert(result);
// all_of
result = all_of(c.begin(), c.end(), u_positive); // ぜんぶ正数だからtrue
assert(result);
result = all_of(c.begin(), c.begin(), u_odd); // ※注意: 空集合に対してはtrueです
assert(result);
// 従来こう書いてた
result = find_if(c.begin(), c.end(), not1(u_positive)) == c.end(); // ~でないものは存在しない
assert(result);
……つづく
