2009-03-19 10 views
3

Warum wird Rückruf nur einmal aufgerufen?Boost Lambda-Verwirrung

bool callback() 
{ 
    static bool res = false; 
    res = !res; 
    return res; 
} 

int main(int argc, char* argv[]) 
{ 
    vector<int> x(10); 

    bool result=false; 
    for_each(x.begin(),x.end(),var(result)=var(result)||bind(callback)); 

    return 0; 
} 

Antwort

8

|| Der Ausdruck short circuits nach dem ersten Mal bind kehrt true.

Das erste Mal, wenn Sie bewerten

result = result || bind(...) // result is false at this point 

bind genannt wird, denn das ist der einzige Weg, um den Wert von false || bind(...) zu bestimmen. Weil bind(...)true zurückgibt, wird result auf true festgelegt.

Jedes anderes Mal, wenn Sie sagen

result = result || bind(...) // result is true at this point 

... der bind(...) Ausdruck nicht ausgewertet, weil es spielt keine Rolle, was es gibt; der Ausdruck true || anything ist immer true und der || Ausdruck short circuits.

Ein Weg, um sicherzustellen, dass bind immer wäre genannt wird, es auf die linke Seite des ||, sich zu bewegen oder die || zu einem && ändern, je nachdem, was Sie mit result versuchen zu erreichen.

+0

Und das ist wegen Boost.Lambda Operator || ist speziell entworfen, um in Verbindung mit der verzögerten Ausführungsfähigkeit des funktor-Objekts, das bind() zurückgibt, kurzzuschließen. Ein gewöhnlicher überladener Operator || schließt NICHT kurz. –

+0

ja, das ist eine nette Eigenschaft davon. normalerweise, wenn Sie den Operator || überlasten, kommt es nicht zu einem Kurzschluss. Boost Lambda scheint sich darum zu kümmern. –

1

In Ihrem speziellen Beispiel, Boost.Lambda bringt Ihnen wirklich nichts. Befreien Sie sich von den Lambda-Teile, und vielleicht sehen Sie klarer sehen, was los ist:

for (int i = 0; i < 10; ++i) 
    result = result || callback(); 

Dieses noch auf Sie verlässt sich zu wissen, dass der || Bediener kurzgeschlossen, wie Daniel explained.

Verwandte Themen