簡體   English   中英

std :: bind類成員函數

[英]std::bind of class member function

我有這個代碼:

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

似乎這個:

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

相當於:

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

為什么?

std::bind() 按值接受其參數。 這意味着在第一種情況下,您將按值傳遞指針 ,從而生成指針的副本。 在第二種情況下,您foo值傳遞foo類型的對象,從而生成Foo類型的對象的副本。

因此,在第二種情況下,對表達式L()的求值會導致在原始對象foo副本上調用成員函數get() ,這可能是您想要的,也可能不是。

這個例子說明了差異(忘記違反三條規則/五條規則,這只是為了說明目的):

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

實例

如果出於任何原因,您不想使用指針形式,則可以使用std::ref()來防止創建參數的副本:

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

她們不一樣。 泛型函數binder std::bind 復制它的參數。 std::bind(&Foo::get,&foo,3)指針被復制,但是當你調用綁定對象時,它仍然適用於原始的foo對象。 std::bind(&Foo::get,foo,3) ,對象foo被復制,后面的調用應用於綁定副本,而不是原始對象。

您可以使用訪問對象內部狀態的成員函數,以兩種方式綁定對象,更改原始對象以及查看結果的不同來測試此操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM