为什么std :: bind可以分配给参数不匹配的std :: function?

lam*_*bda 13 c++ bind function std c++11

我的代码如下:

#include <functional>
#include <iostream>
using namespace std;
void F(int x) {
  cout << x << endl;
}
int main() {
  std::function<void(int)> f1 = std::bind(F, std::placeholders::_1);
  f1(100);  // This works, will print 100.

  int x = 0;
  std::function<void()> f2 = std::bind(F, x);
  f2();  // This works, will print 0.

  std::function<void(int)> f3 = std::bind(F, x);
  f3(200);  // BUT WHY THIS WORKS?????? It prints 0.
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的编译器信息是:Apple LLVM版本6.0(clang-600.0.56)(基于LLVM 3.5svn)目标:x86_64-apple-darwin13.4.0线程模型:posix

Dre*_*ann 21

这是正确的行为.

std::bind需要这种宽松度以适应自己的规格.

考虑一下std::placeholders,它用于标记传递给绑定函数的参数.

using std::placeholders;
std::function<void(int)> f2 = std::bind( F, _1 );
//  Parameter 1 is passed to                ^^
//  the bound function.

f2(7); // The int 7 is passed on to F
Run Code Online (Sandbox Code Playgroud)

同样,_2第二个参数,_3第三个参数,依此类推.

这提出了一个有趣的问题.这个函数对象应该如何表现?

auto f3 = std::bind( F, _3 );
Run Code Online (Sandbox Code Playgroud)

正如您可能想象的那样,它遵循自己的承诺将第三个参数传递给F.这意味着它对前两个参数没有任何作用.

f3(10, 20, 30); // The int 30 is passed on to F. The rest?  Ignored.
Run Code Online (Sandbox Code Playgroud)

所以这是预期的行为,也可能是std::bindlambdas 唯一的"特性" ,即使在C++ 14和C++ 17中也是如此.

生成的对象std::bind旨在接受和忽略任何无关的参数.

  • @DawidDrozd如果`F`有任何参数,绑定必须提供它们 (2认同)