У меня есть функция вида:
void DoSomething(const boost::function<bool ()>& condition, other stuff);
Эта функция выполняет некоторую работу и возвращает только когда условие выполнено. Условие было выражено как аргумент функтора, потому что я хочу предоставить разные условия на разных сайтах вызовов.
Теперь, это довольно просто использовать напрямую, но требует объявления множества маленьких одноразовых функций или объектов-функторов, которых я бы хотел избежать, если это возможно. Я искал в лямбда-библиотеке Boost возможные способы покончить с этим, но я думаю, что упускаю что-то фундаментальное; Я просто не могу заставить его делать то, что я хочу.
Один случай, который меня озадачил на данный момент: у меня есть коллекция std::vector
под названием data
; условие, за которым я следую, - это когда size()
этой коллекции достигает определенного порога. По сути, я хочу, чтобы мой функтор condition
возвращал true, когда data.size() >= threshold
, и false в противном случае. Но мне было трудно выразить это в лямбда-синтаксисе.
Лучшее, что я смог до сих пор придумать (который, по крайней мере, компилируется, хотя и не работает), это:
boost::function<bool (size_t)> ge = boost::bind(std::greater_equal<size_t>(),
_1, threshold);
boost::function<size_t ()> size = boost::bind(&std::vector<std::string>::size,
data);
DoSomething(boost::lambda::bind(ge, boost::lambda::bind(size)), other stuff);
При входе в DoSomething
размер равен 0 - и хотя размер увеличивается в ходе выполнения, вызовы condition()
всегда, кажется, получают размер 0. Отслеживание этого (что является немного сложнее из внутренних элементов Boost), хотя он, кажется, вызывает greater_equal
каждый раз, когда condition()
оценивается, он, кажется, не вызывает size()
.
Так что фундаментального, что я полностью испортил? Есть ли более простой способ выразить подобные вещи (при этом сохраняя код как можно более встроенным)?
В идеале я бы хотел, чтобы он был как можно ближе к беглости кода, эквивалентного C #:
DoSomething(delegate() { return data.size() >= threshold; }, other stuff);
DoSomething(() => (data.size() >= threshold), other stuff);