2

私がこのタイプを持っているとしましょう:

typedef boost::function<bool (Foo)> filter_function;

そして、これらの「フィルター関数」のベクトル:

std::vector<filter_function> filters;

すべてのフィルター関数を 1 つずつ呼び出したい場合、最後の呼び出しのみが true を返しました。

以前の質問に触発されて、私は次のように書きました:

bool Bar::filterFoo(Foo& foo)
{
  return (std::find_if(filters.begin(), filters.end(), boost::lambda::bind(boost::lambda::_1, foo)) == filters.end());
}

しかし、これは間違っています。ラムダの戻り値は否定されるべきです。

std::not1、さまざまな場所で使用しようとしstd::not2ましたが、(かなり冗長な)コンパイルエラーにならないバリエーションが見つかりませんでした。

これを行う正しい方法は何ですか?

4

1 に答える 1

2

戻り値を単純に否定できます。

bool Bar::filterFoo(Foo& foo)
{
  return (std::find_if(filters.begin(), filters.end(), !boost::lambda::bind(boost::lambda::_1, foo)) == filters.end());
}

または、c++0X のラムダを使用できます

bool Bar::filterFoo(Foo& foo)
{
    return (std::find_if(filters.begin(), filters.end(), [&foo](filter_function& f){
        return !f(foo);
    }
    ) == filters.end());
}

少なくとも VS2010 で機能する完全な例を示します。

#include <iostream>
#include <vector>
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/bind.hpp>
#include <boost/lambda/bind.hpp>

using namespace std;

struct Foo{};

typedef boost::function<bool (Foo)> filter_function;
std::vector<filter_function> filters;

static int g_c = 0;
bool MyFunc(Foo /*foo*/)
{
    if(g_c > 1)
        return true;
    g_c++;
    return false;
}
bool filterFoo(Foo& foo)
{
    return (std::find_if(filters.begin(), filters.end(), boost::lambda::bind(boost::lambda::_1, foo)) == filters.end());
}
bool negatefilterFoo(Foo& foo)
{
    return (std::find_if(filters.begin(), filters.end(), !boost::lambda::bind(boost::lambda::_1, foo)) == filters.end());
}

int main() 
{
    Foo f;
    filters.push_back(boost::bind(&MyFunc, _1));
    filters.push_back(boost::bind(&MyFunc, _1));
    filters.push_back(boost::bind(&MyFunc, _1));
    std::cout << filterFoo(f) << std::endl;
    std::cout << negatefilterFoo(f) << std::endl;
    return 0;
}

私のマシンでは 0 と 1 が返されます。

于 2011-06-28T14:26:25.767 に答える