如何使用boost bind组合多个仿函数?

时间:2012-05-21 14:35:41

标签: c++ boost lambda boost-bind

我遇到过一种情况,我有一系列成员函数可以生成关于目标对象的简单信息:

double MyDoc::GetX(thing)
double MyDoc::GetY(thing)
etc.

我在同一个类中创建了一些“非常格式化”的成员函数:

string MyDoc::PrintOne(thing, std::function<double (THING*)>)

您会注意到漂亮的打印机功能需要数据功能 - 即它是可组合的,这样我就可以创建有关目标的各种类型的信息,并为它生成“漂亮的打印”字符串。

在直接使用中,这种技术非常有效。

然而,我真正想要的当前应用程序是组合这些实体的多个层 - 即有效地为上述组合创建一个仿函数(函数对象),这样我就可以指定漂亮的打印机功能,并且它是数据采集功能,稍后再调用。模式是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 ++ lambda语法混淆,或者我可能只是从根本上误解了一些东西?

基本上,我想要编写一个函数Z,它接受一个THING *和另一个函数X,它也接受一个THING *,并且使用它自己的逻辑,为给定的THING *生成一个字符串输出。

我有变化 - 有些采用两种数据访问类型函数,或者可能是一个bool +数据访问器。无所谓 - 底线应该是相同的:

如何在Z中组合Z - > F(x,G(x))?

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

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))
)

标题为“using nested binds for function composition”的文档部分对此进行了概述。