【问题标题】:Why std::bind can be assigned to argument-mismatched std::function?为什么 std::bind 可以分配给参数不匹配的 std::function?
【发布时间】:2015-05-23 10:13:42
【问题描述】:

我的代码如下:

#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;
}

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

【问题讨论】:

  • cppreference 说(关于operator() 的主题,以获取std::bind 的返回值):如果在调用 g() 时提供的某些参数不匹配存储在 g 中的任何占位符,未使用的参数将被评估并丢弃。

标签: c++ function c++11 bind std


【解决方案1】:

这是正确的行为。

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

同样,第二个参数为_2,第三个参数为_3,以此类推。

这带来了一个有趣的问题。这个函数对象应该如何表现?

auto f3 = std::bind( F, _3 );

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

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

所以这是预期的行为,并且可能是std::bind 对 lambdas 拥有的唯一“功能”,即使在 C++14 和 C++17 中也是如此。

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

【讨论】:

  • 可以肯定。这也是正确的? std::function&lt;void(int)&gt; f3 = std::bind(F);
  • @DawidDrozd not if F 有任何参数,绑定必须提供它们
猜你喜欢
  • 2016-12-18
  • 1970-01-01
  • 2019-11-16
  • 1970-01-01
  • 2021-07-24
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
相关资源
最近更新 更多