为什么 std::bind 可以分配给参数不匹配的 std::function?
Why std::bind can be assigned to argument-mismatched std::function?
我有如下代码:
#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
这是正确的行为。
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
保留 lambda 的行为,即使在 C++14 和 C++17 中也是如此。
std::bind
生成的对象旨在接受和忽略任何无关参数。
我有如下代码:
#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
这是正确的行为。
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
保留 lambda 的行为,即使在 C++14 和 C++17 中也是如此。
std::bind
生成的对象旨在接受和忽略任何无关参数。