22

假设我有一个带有两个参数的函数,

void f(int x, int y);

我想绑定其中一个。我可以使用std::bind如下:

auto partiallyBoundF = std::bind(f, 10, _1);

partiallyBoundF只接受一个参数,但我可以用多个参数来调用它。第一个以外的参数甚至不必是任何有意义的类型:

partiallyBoundF(20, 0);
partiallyBoundF(0, 44, -99, "Hello", 4.5, true, []{});

允许从返回的对象bind传递额外参数的目的是什么?它允许编译调用错误,而这些错误会在其他任何地方被拒绝。

4

1 回答 1

19

忽略额外的参数实现起来要简单得多,而且实际上很有用。

在 libstdc++ (g++) 等典型实现中,采用的方法是将operator()参数收集到一个元组中,然后让std::placeholder绑定参数根据需要提取它们。强制参数计数需要计算使用的占位符的数量,这将非常复杂。请注意,绑定可调用对象可以是具有多个或模板化operator()调用模式的仿函数,因此operator()无法使用单个“正确”签名生成绑定对象。

另请注意,您可以编写:

std::bind(&foo, std::placeholders::_1, std::placeholders::_3);

即明确忽略绑定对象的第二个参数。如果bind强制执行其参数计数,您将需要另一种方法来指定例如第四个参数也将被忽略。

至于有用性,请考虑将成员信号处理程序绑定到信号:

sig.connect(std::bind(&C::on_sig, this, param, std::placeholders::_1));

如果sig有额外的无用发射参数,那么它们会被bind对象简单地忽略;否则,将同一个处理程序绑定到多个信号将需要编写多个转发包装器而没有真正的目的。

于 2012-11-06T13:58:23.180 回答