2012-01-26 4 views
0

Предположим, я хочу использовать зЬй :: LOWER_BOUND на станд :: вектор указателей, как это:повышение :: связать или повышение :: лямбда на станд :: LOWER_BOUND

struct X { 
    int x; 
    double y; 
}; 

// overloads for normal comparisons 
bool operator< (int left, const X& right) { return left < right.x; } 
bool operator< (const X& left, int right) { return left.x < right; } 

std::vector<X*> v; 

int searchValue = 5; 
std::vector<X*>::iterator it = std::lower_bound(v.begin(), v.end(), searchValue, 
    ? // what the heck do I put here? 
); 

ли я использовать повышение :: bind или boost :: lambda здесь, и если да, то как?

Я думаю, что бы это было бы так:

std::lower_bound(v.begin(), v.end(), searchValue, searchValue < *_1); 

Однако я получаю недопустимую ошибку разыменования на этом.

+0

Boost.Lambda официально осуждается с момента выхода [Boost.Phoenix] (http://www.boost.org/libs/phoenix/) v3, поэтому _real_ ответ использовать Boost.Phoenix. I.e., код, который у вас хорошо работает с Boost.Phoenix без каких-либо изменений (за исключением того, что аргументы вашего 'operator <' обращаются назад). – ildjarn

+0

Обычно я бы сказал 'std :: less ()', но вы сравниваете 'int' с' X', чтобы это не сработало. – Flexo

+0

К сожалению, я все еще на boost 1.43, поэтому Boost.Phoenix недоступен :( – syvex

ответ

0

Получил это после некоторых проб и ошибок. Boost.Bind не будет работать здесь, и компилятор будет запутан с использованием заполнителя. Boost.Bind использует _1 в анонимном корневом пространстве имен. Boost.Lambda использует его под расширением names :: lambda :: _ 1.

Кроме того, у меня был неправильный порядок со сравнением.

#include <boost/lambda/lambda.hpp> 

// ... 

std::vector<X*>::iterator it = std::lower_bound(v.begin(), v.end(), searchValue, 
    *boost::lambda::_1 < searchValue 
); 
+0

Однако VS 2008 жалуется, когда вы меняете X * на boost :: shared_ptr . Не уверен, что с этим. VS 2010 отлично работает. – syvex

0

Попробуйте следующее

struct MyLessThan 
{ 
    bool operator()(const X* xVal, int iVal) 
    { 
     return xVal->x < iVal; 
    } 
}; 

std::vector<X*> v; 

int searchValue = 5; 
std::vector<X*>::iterator it = std::lower_bound(v.begin(), v.end(), searchValue, MyLessThan()); 

Это должно работать.

+0

Нет, нужен указатель указателя на 'operator()', потому что указатели 'std :: vector' сохраняют указатели. – Xeo

+0

@Xeo :) Я не заметил, что это был вектор указателей. У него также была другая ошибка. Спасибо за исправление. – broc

+0

Это будет работать, но я надеялся избежать определения пользовательского предиката. использование boost :: bind или lambdas. – syvex

Смежные вопросы