In lambda functions syntax, what purpose does a 'capture list' serve?

前端 未结 5 1574
一个人的身影
一个人的身影 2020-12-24 04:00

Taken from an answer to this question, as an example, this is a code that calculates the sum of elements in a std::vector:

std::for_each(
    ve         


        
5条回答
  •  清歌不尽
    2020-12-24 04:09

    Consider this:

    std::function
    make_generator(int const& i)
    {
        return [i] { return i; };
    }
    
    // could be used like so:
    int i = 42;
    auto g0 = make_generator(i);
    i = 121;
    auto g1 = make_generator(i);
    i = 0;
    
    assert( g0() == 42 );
    assert( g1() == 121 );
    

    Notice that in this situation the two generators that have been created each have their own i. This is not something you can recreate with ordinary functions, and thus why those don't use capture lists. Capture lists solve one version of the funarg problem.

    Are lambda functions more than just nameless functions?

    That is a very smart question. What lambda expressions create are in fact more powerful than regular functions: they're closures (and the Standard indeed refer to the objects that lambda expressions create as 'closure objects'). To put it briefly, a closure is a function combined with a bound scope. C++ syntax has chosen to represent the function bit in a familiar form (argument list with delayed return type with function body, some parts optional) while the capture list is the syntax that specifies which local variable will participate in the bound scope (non-local variables are automatically introduced).

    Note that other languages with closures usually do not have a construct similar to C++ capture lists. C++ has made the design choice of capture-lists due to its memory model (local variable only live as long as the local scope) and its philosophy of not paying for what you don't use (making local variables now automagically live longer if they're captured might not be desirable in each and every case).

提交回复
热议问题