Как мне составить несколько функторов, используя 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))
)

Это изложено в разделе документации, озаглавленном " Использование вложенных связываний для композиции функций".

Другие вопросы по тегам