Как мне составить несколько функторов, используя Boost Bind?
У меня есть ситуация, когда у меня есть ряд функций-членов, которые производят простую информацию о целевом объекте:
double MyDoc::GetX(thing)
double MyDoc::GetY(thing)
etc.
Я сделал несколько "довольно форматирующих" функций-членов в одном классе:
string MyDoc::PrintOne(thing, std::function<double (THING*)>)
Вы заметите, что функция pretty-printer принимает функцию данных, то есть она может быть составлена так, что я могу создавать различные типы информации о цели и создавать для нее строку "pretty print".
При прямом использовании эта техника прекрасно работает.
Тем не менее, что я действительно хочу для моего текущего приложения, так это составить несколько слоев таких объектов - т.е. эффективно создать функтор (объект функции) для вышеупомянутой композиции в целом, так что я могу указать функцию pretty-printer и ее данные. Функция приобретения, и позвоните, что позже. Шаблон z(x) -> f(x, g(x)):
auto Z = [&] (THING* thing) {
return boost::bind(
&MyDoc::PrintOne,
this,
_1,
boost::bind(MyDoc::GetX, this, _1));
}
И вот тут я сталкиваюсь с проблемами. Я иду по кругу, пытаясь понять синтаксис правильно, или, может быть, меня путают с синтаксисом boost::bind и синтаксисом C++ лямбда, или, может быть, я просто что-то в корне неправильно понимаю?
По сути, я хочу составить функцию Z, которая принимает THING*, и другую функцию X, которая также принимает THING* и, используя собственную логику, создает строковый вывод для данного THING*.
У меня есть варианты - некоторые принимают две функции типа средства доступа к данным, или, возможно, средство доступа к данным bool +. Не имеет большого значения - нижняя строка должна быть такой же:
Как мне составить Z, где Z -> F(x, G(x))?
Спасибо за любую помощь!
1 ответ
boost::bind
(а также std::bind
) охотно оценивает вложенные выражения связывания, чтобы то, что у вас было, соответствовало бы подписи string MyDoc::PrintOne(THING*, double)
, Чтобы предотвратить нетерпеливую оценку и вернуть вложенное выражение связывания напрямую (подходит для создания std::function<>
), используйте boost::protect
:
boost::bind(
&MyDoc::PrintOne,
this,
_1,
boost::protect(boost::bind(&MyDoc::GetX, this, _1))
)
Это изложено в разделе документации, озаглавленном " Использование вложенных связываний для композиции функций".