読者です 読者をやめる 読者になる 読者になる

methaneのブログ

このブログに乗せているサンプルコードはすべてNYSLです。

C++で誰もが嵌る罠

program C++

関数のローカルでfunctorを作って、その関数オブジェクトをアルゴリズムに渡せない罠。

#include <iostream>
#include <numeric>
#include <ext/numeric>
#include <vector>
#include <algorithm>

using namespace std;

int main(void)
{
        vector<int> v(100);
        iota(v.begin(), v.end(), 5);
        struct print_v : public unary_function<int,void> {
                void operator()(int i) { cout << i << '\n'; } };
        for_each(v.begin(), v.end(), print_v());

        return 0;
}

print_vが宣言されている名前空間がローカルだから、for_each()から見れないという罠。
そして、何とかしようとして、

        for_each(v.begin(), v.end(), (unary_function<int,void>)print_v());

とすると、for_eachの引数が参照渡しじゃなくて値渡しになっているので、やっぱりダメと。そもそも unary_function で virtual Result operator()(Arg a) = 0;とかしてくれてないしね。
無名関数を使うなら、boost::lambda。

#include <iostream>
#include <numeric>
#include <ext/numeric>
#include <vector>
#include <algorithm>
#include <boost/lambda/lambda.hpp>

using namespace std;
using namespace boost::lambda;

int main(void)
{
        vector<int> v(100);
        iota(v.begin(), v.end(), 5);
        for_each(v.begin(), v.end(), cout << _1 << '\n');

        return 0;
}

ちゃんと動く。lambda凄い。lambdaエライ。

そして、C++で無名関数を使う難しさを忘れてた俺エラクナイ。罰としてboost/lambda/lambda.hpp読む。

で、コード見たら判るとおり、id:odzさんが使っていたiotaがSGIではだけどg++ではになっていることを調べてた。標準C++ではどうなってるんだろ・・・。帰ったらプログラミング言語C++を読む。