Как отрицать boost :: lambda: bind? - PullRequest
2 голосов
/ 28 июня 2011

Допустим, у меня есть этот тип:

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

И вектор этих "функций фильтра":

std::vector<filter_function> filters;

Если вы хотите вызывать все функции фильтра, одну за другой, и только последний вызов вернул 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 в разных местах, но не смог найти ни одного варианта, который не заканчивался бы (довольно многословно) ошибкой компиляции.

Как правильно это сделать?

1 Ответ

2 голосов
/ 28 июня 2011

Вы можете просто отменить возвращаемое значение.

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.

...