2013-03-21 28 views
5

Jednym prostym przykładem, który wyjaśnia, w jaki sposób można używać , jest:W jaki sposób można użyć std :: bind?

Załóżmy, że mamy funkcję 3 argumentów: f3 (x, y, z). Chcemy mieć funkcję 2 argumentów, która jest zdefiniowana jako: f2(x,y) = f3(x,5,y). W C++ możemy łatwo zrobić z std::bind:

auto f2 = std::bind(f3, _1, 5, _2); 

Ten przykład jest dla mnie jasne: std::bind wykonuje funkcję jako pierwszy argument, a następnie zajmuje n inne argumenty, gdzie n to liczba argumentów funkcji jest to pierwszy argument dla std::bind.

Jednak znalazłem innego wykorzystania wiąże:

void foo(int &x) 
{ 
    ++x; 
} 


int main() 
{ 
    int i = 0; 

    // Binds a copy of i 
    std::bind(foo, i)(); // <------ This is the line that I do not understand. 
    std::cout << i << std::endl; 

} 

Jest oczywiste, że foo ma jeden argument i std::bind została ona ustawiona na i. Ale dlaczego używamy kolejnej pary nawiasów po (foo, i)? I dlaczego nie używamy wyjścia z std::bind? Chodzi mi o to, dlaczego nie mamy auto f = std::bind(foo, i)?

+2

Co na ziemi jest "\\\"? –

+0

To miał być komentarz: // – Roman

Odpowiedz

8

Linia

std::bind(foo, i)(); 

odpowiada:

auto bar = std::bind(foo, i); 
bar(); 

Tworzy związanego funktor, a następnie natychmiast nazywa go (za pomocą drugiej pary nawiasach).

Edytuj: W imię dokładności (i wskazane przez @Roman, @daramarak) dwa nie są faktycznie równoważne wywoływaniu funkcji bezpośrednio: i jest przekazywane przez wartość do std :: bind. Kod odpowiednik nazywając foo bezpośrednio z I byłoby:

auto bar = std::bind(foo, std::ref(i)); 
bar(); 
+0

Usunięto moje uwagi na temat nieważnego sprzeciwu – daramarak

2

Twoje dwa pytania dość dużo odpowiedzieć siebie. Końcowy () jest zwykłym wywołaniem funkcji. W związku z tym wyrażenie oznacza: "Powiązanie i z foo, da to funkcję bez parametrów, a następnie wywoła wynikową funkcję." Ponieważ autor kodu zdecydował, że funkcja nie jest już potrzebna po wywołaniu, nie jest nigdzie przechowywana.

3

Wiąże foo do tymczasowego obiektu, a następnie wywołać ją natychmiast:

auto f = std::bind(foo, i); 
    f(); 

pojedyncze wersja linia:

std::bind(foo, i)(); 
0

Ponieważ linia

std::bind(foo, i)() ; 

... robi to samo co ...

foo(i); 

... to nie jest tak naprawdę "użycie" std :: bind, które można napotkać w rzeczywistym kodzie, ale służy jako prosta ilustracja tego, co robi std :: bind, jak wyjaśniono w innych odpowiedzi.

Jak zwykle zwracasz uwagę na wynik wiązania i wywołujesz go gdzieś indziej, w przeciwnym razie nie ma sensu komplikowanie kodu za pomocą std :: bind.

Powiązane problemy