[英]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.