std :: bind(x,y)到底有什么用呢?

Joh*_*itb 13 c++ stdbind c++11

std::bind在第32小节中读到了N3225中的描述20.8.10.1.它说下面应该打印1,但我认为bind应该复制它的参数,因此它应该打印0.如果想要引用传递的参数,则需要使用std::ref,对吧?

void f(int &a) { a = 1; }

int main() {
  int a = 0;
  std::bind(f, a)();
  std::cout << a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会的产出0,同意我认为的工作.但是N3225说std::bind(f, a1)应该返回一个调用包装器,当调用时wrapper()将调用INVOKE(f, v1),其中v1应该是a(我传入的参数,换句话说,使用binds传入的参数,这是一个完美的转发参数std::forward<A1>(a1)).

INVOKE(f, a)由20.8.2定义为f(a).因此,这定义了对返回的调用包装器调用传递原始参数.我错过了什么?

sel*_*tze 5

它说以下应该打印1

不,它没有说.

如果想要引用传递的参数,则需要使用std :: ref,对吧?

是.

但是N3225说std :: bind(f,a1)应该返回一个调用包装器,当被wrapper()调用时会调用INVOKE(f,v1),其中v1应该是a(我传入的参数,换句话说,使用绑定的传入参数,这是一个完美的转发参数,std :: forward(a1​​)).

那就是你错了.您在bind-call中传入的"绑定参数"以新创建的对象形式存储,TiD每个对象都是从中构造forward<Ti>(ti).通过说"tid是由" 构造的 TiD型的左值",可以合理地清楚地说明这一点std::forward<Ti>(ti).由于参考包装的特殊处理,还有一个额外的"转换层".见20.8.10.1.2/10,说明如何viVi涉及到tidTiD.


Joh*_*itb 2

哇,这令人难以置信。它定义v1tid和 it 如下(ti是第 i 个完美转发绑定参数,并且TiD是该参数的衰退类型 - 即数组变成指针等)。

tidTiD是由以下构造的类型的左值std::forward<Ti>(ti)

好吧,我确实说了,这tid就是std::forward<Ti>(ti)左值!但这并不是它真正的意思。它的意思是

tid是一个类型的左值TiD,引用由以下内容构造的对象std::forward<Ti>(ti)

现在它变得更有意义了。因为 ifstd::forward<Ti>(ti)实际上是一个右值怎么办?“左值...构造自...”意味着我们从“...”创建一个新对象并使左值引用它。