函数签名为std::bind()
如下 https://en.cppreference.com/w/cpp/utility/functional/bind:
template< class F, class... Args >
/*unspecified*/ bind( F&& f, Args&&... args );
So args
如果我理解正确的话,是一个可变参数模板通用参考。传统通用引用的模板类型推导规则如下:
- 如果传递给 T 的参数是左值,则 T 被推导为左值引用
- 如果传递给 T 的参数是右值,则 T 被推导为左值
...我认为这些规则适用于中的每个参数args
单独地,这意味着所有左值都传递到std::bind()
作为函子的参数将通过引用传递。但这与下面的程序相矛盾:
#include <iostream>
#include <functional>
void function(int& n) {
n++;
}
int main() {
int n = 0;
auto functor = std::bind(function, n);
functor();
std::cout << n << std::endl; // 0, not 1.
return 0;
}
为了得到n
要通过引用传递,您必须通过显式执行此操作std::ref(n)
,鉴于我对通用引用和完美转发知之甚少,这确实让我感到困惑。如何std::bind()
当它使用通用引用时按值获取任何内容,否则会消耗左值作为引用?
它与签名几乎无关,它是一种设计选择。std::bind
当然必须以某种方式存储其所有绑定参数并将它们存储为值。 “通用性”仅用于正确构建它们 - 通过移动或复制。
std::ref
也是按值存储,但由于其性质,包装的对象是按引用“存储”的。
std::thread
具有完全相同的行为。有人可能会说,(移动)默认构造一个副本更安全,因为返回的两个对象往往比最有可能被捕获的本地对象寿命更长。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)