为什么从bind返回的对象会忽略额外的参数?

时间:2022-10-16 20:11:55

Suppose I have a function that takes two arguments,

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

void f(int x, int y);

and I want to bind one of them. I can use std::bind as follows:

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

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

partiallyBoundF takes only one argument, but I can call it with more than one. The arguments beyond the first don't even have to be of a type that makes any sense:

partiallyBoundF只接受一个参数,但我可以用多个参数调用它。超越第一个的论点甚至不必是一个有意义的类型:

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

What is the purpose of permitting objects returned from bind to be passed extra arguments? It allows calling errors to compile that would be rejected anyplace else.

允许从bind返回的对象传递额外参数的目的是什么?它允许编译调用错误,否则将被拒绝。

1 个解决方案

#1


16  

Ignoring extra arguments is a lot simpler to implement, and can actually be useful.

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

In a typical implementation e.g. libstdc++ (g++), the approach taken is to collect the operator() arguments into a tuple and then let the std::placeholder bind arguments extract them as required. Enforcing argument count would require counting the number of used placeholders, which would be pretty complicated. Note that the bind callable can be a functor with multiple or templated operator() call patterns, so the bind object operator() can't be generated with a single "correct" signature.

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

Also note that you can write:

另请注意,您可以写:

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

i.e. explicitly ignoring the second argument to the bind object. If bind enforced its argument count you would need an additional way to specify that e.g. a fourth argument was also to be ignored.

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

As for usefulness, consider binding a member signal handler to a signal:

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

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

If sig has extra unwanted emission parameters, then they are simply ignored by the bind object; otherwise, binding the same handler to multiple signals would require writing multiple forwarding wrappers for no real purpose.

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

#1


16  

Ignoring extra arguments is a lot simpler to implement, and can actually be useful.

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

In a typical implementation e.g. libstdc++ (g++), the approach taken is to collect the operator() arguments into a tuple and then let the std::placeholder bind arguments extract them as required. Enforcing argument count would require counting the number of used placeholders, which would be pretty complicated. Note that the bind callable can be a functor with multiple or templated operator() call patterns, so the bind object operator() can't be generated with a single "correct" signature.

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

Also note that you can write:

另请注意,您可以写:

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

i.e. explicitly ignoring the second argument to the bind object. If bind enforced its argument count you would need an additional way to specify that e.g. a fourth argument was also to be ignored.

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

As for usefulness, consider binding a member signal handler to a signal:

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

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

If sig has extra unwanted emission parameters, then they are simply ignored by the bind object; otherwise, binding the same handler to multiple signals would require writing multiple forwarding wrappers for no real purpose.

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