std::bind()
przyjmuje argumenty według wartości. Oznacza to, że w pierwszym przypadku podajesz wskaźnik po wartości, co powoduje skopiowanie wskaźnika. W drugim przypadku przekazujesz obiekt typu foo
według wartości, co daje kopię obiektu typu Foo
.
W konsekwencji, w drugim przypadku oceny ekspresji L()
wywołuje funkcję składową get()
się powoływać na kopii oryginalnego obiektu foo
, które mogą lub nie mogą być, co chcesz.
Ten przykład ilustruje różnicę (zapomnieć o naruszenie Reguły trzy/Reguły Piątki, to tylko w celach ilustracyjnych):
#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.
Jeśli z jakiegokolwiek powodu nie chcesz, aby skorzystać z formularza wskaźnika, można użyć std::ref()
aby zapobiec kopii argumentu z tworzonej:
auto L = std::bind(&Foo::get, std::ref(foo), 3);
To nie jest. Jeden wiąże wskaźnik, drugi wiąże * kopię *. – Xeo
Dla tego, co jest warte, możesz także przekazać inteligentny wskaźnik (dowolny typ, który implementuje 'operator->', aby zwrócić 'foo *') jako drugi argument. Wypróbuj go za pomocą 'std :: shared_ptr'. –
duplikat: http: //stackoverflow.com/questions/15264003/using-stdbind- with-member-function-use-object-pointer- or-not-for-this-argumen Chociaż lubię obie odpowiedzi ... – nephewtom