简体   繁体   English

std :: bind类成员函数

[英]std::bind of class member function

I have this code: 我有这个代码:

#include <iostream>
#include <functional>

struct Foo
{
        int get(int n) { return 5+n; }
};

int main()
{
        Foo foo;
        auto L = std::bind(&Foo::get, &foo, 3);

        std::cout << L() << std::endl;

        return 0;
}

Seems that this: 似乎这个:

auto L = std::bind(&Foo::get, &foo, 3);

is equivalento to: 相当于:

auto L = std::bind(&Foo::get, foo, 3);

Why? 为什么?

std::bind() accepts its arguments by value . std::bind() 按值接受其参数。 This means that in the first case you are passing a pointer by value, resulting in the copy of a pointer. 这意味着在第一种情况下,您将按值传递指针 ,从而生成指针的副本。 In the second case, you are passing an object of type foo by value, resulting in a copy of an object of type Foo . 在第二种情况下,您foo值传递foo类型的对象,从而生成Foo类型的对象的副本。

As a consequence, in the second case the evaluation of the expression L() causes the member function get() to be invoked on a copy of the original object foo , which may or may not be what you want. 因此,在第二种情况下,对表达式L()的求值会导致在原始对象foo副本上调用成员函数get() ,这可能是您想要的,也可能不是。

This example illustrates the difference (forget the violation of the Rule of Three/Rule of Five, this is just for illustration purposes): 这个例子说明了差异(忘记违反三条规则/五条规则,这只是为了说明目的):

#include <iostream>
#include <functional>

struct Foo
{
    int _x;

    Foo(int x) : _x(x) { }

    Foo(Foo const& f) : _x(f._x)
    {
        std::cout << "Foo(Foo const&)" << std::endl;
    }

    int get(int n) { return _x + n; }
};

int main()
{
   Foo foo1(42);

   std::cout << "=== FIRST CALL ===" << std::endl;
   auto L1 = std::bind(&Foo::get, foo1, 3);
   foo1._x = 1729;
   std::cout << L1() << std::endl; // Prints 45

   Foo foo2(42);

   std::cout << "=== SECOND CALL ===" << std::endl;
   auto L2 = std::bind(&Foo::get, &foo2, 3);
   foo2._x = 1729;
   std::cout << L2() << std::endl; // Prints 1732
}

Live example . 实例

If, for any reason, you don't want to use the pointer form, you can use std::ref() to prevent a copy of the argument from being created: 如果出于任何原因,您不想使用指针形式,则可以使用std::ref()来防止创建参数的副本:

auto L = std::bind(&Foo::get, std::ref(foo), 3);

They are not the same. 她们不一样。 The generic function binder std::bind copies it's arguments. 泛型函数binder std::bind 复制它的参数。 In the case of std::bind(&Foo::get,&foo,3) , the pointer is copied, but when you call the bound object it still applies to the original foo object. std::bind(&Foo::get,&foo,3)指针被复制,但是当你调用绑定对象时,它仍然适用于原始的foo对象。 In std::bind(&Foo::get,foo,3) the object foo is copied, and the later call applies to the bound copy, not to the original object. std::bind(&Foo::get,foo,3) ,对象foo被复制,后面的调用应用于绑定副本,而不是原始对象。

You can test this by using a member function that accesses internal state of the object, bind the object in both ways, change the original object and see how the results differ. 您可以使用访问对象内部状态的成员函数,以两种方式绑定对象,更改原始对象以及查看结果的不同来测试此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM