Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么bind返回的对象会忽略额外的参数?_C++_C++11_Stdbind - Fatal编程技术网

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

C++ 为什么bind返回的对象会忽略额外的参数?,c++,c++11,stdbind,C++,C++11,Stdbind,假设我有一个接受两个参数的函数 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, [

假设我有一个接受两个参数的函数

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
返回的对象传递额外参数的目的是什么?它允许调用将在任何地方被拒绝的错误进行编译。

忽略额外的参数更容易实现,而且实际上非常有用

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

还请注意,您可以编写:

std::bind(&foo, std::placeholders::_1, std::placeholders::_3);
i、 e.显式忽略绑定对象的第二个参数。如果
bind
强制执行其参数计数,则需要另外一种方法来指定,例如,第四个参数也将被忽略

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

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

如果
sig
具有额外的不需要的发射参数,则
bind
对象将忽略这些参数;否则,将同一个处理程序绑定到多个信号将需要编写多个转发包装,而没有实际用途。

什么编译器?我猜这可能只是一个不一致的编译器(因为允许这些附加参数真的没有意义,我怀疑标准是否允许)。例如,MSVC模拟可变模板,只需定义每个可变模板以获取最大可能的模板参数,并将这些参数默认为某种NIL类型。也许这就是你行为的原因?@ChristianRau:这是标准的一部分。这也是TR1的一部分。20.8.2/4评论说,预期的实现是让可变模板化的
运算符()
简单地接受传递给它的任何内容,而不考虑参数的类型或数量。TR1具有类似的措辞。在您的情况下,f(w1,…,wN)其中
N=sizeof…(绑定参数)
(绑定调用的参数数)应为有效表达式,请参见20.8.9.1.2/2和20.8.2/1。编辑:它不允许以任何其他方式调用它。@KnowitAllWannab它允许获取“任意参数列表”,但“将参数传递到包装的可调用对象”。我认为这是否允许这种调用(毕竟,
f(int,double,随便什么)
是无效的)。@ChristianRau:MSVC11和11月的CTP毫无怨言地接受额外的参数。“更有用”-我会对此进行辩论。这打破了强力打字。如果需要,仍然可以使用严格的
std::bind
模拟这种行为,只需使用接受可变参数的代理函子即可。@KonradRudolph绑定表达式在一般情况下没有定义良好的类型,如果其可调用的是具有多个
运算符()的函子
s。您可以使用lambda忽略第四个参数。但这不是很好。@KonradRudolph事实上,
bind
表达式的有效调用签名集在一般情况下是不可计算的,通过明显的构造,即使对于严格的
std::bind