This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 110b. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2023-01-15


750. Implementation constraints on reference-only closure objects

Section: 7.5.5.2  [expr.prim.lambda.closure]     Status: CD2     Submitter: Daveed Vandevoorde     Date: 10 December, 2008

N2800 comment US 73

[Voted into the WP at the July, 2009 meeting as part of N2927.]

Consider an example like:

    void f(vector<double> vec) {
      double x, y, z;
      fancy_algorithm(vec, [&]() { /* use x, y, and z in various ways */ });
    }

7.5.5 [expr.prim.lambda] paragraph 8 requires that the closure class for this lambda will have three reference members, and paragraph 12 requires that it be derived from std::reference_closure, implying two additional pointer members. Although 9.3.4.3 [dcl.ref] paragraph 4 allows a reference to be implemented without allocation of storage, current ABIs require that references be implemented as pointers. The practical effect of these requirements is that the closure object for this lambda expression will contain five pointers. If not for these requirements, however, it would be possible to implement the closure object as a single pointer to the stack frame, generating data accesses in the function-call operator as offsets relative to the frame pointer. The current specification is too tightly constrained.

Lawrence Crowl:

The original intent was that the reference members could be omitted from the closure object by an implementation. The problem we had was that we want the call to f in

    extern f(std::reference_closure<void()>);
    extern f(std::function<void()>);
    f([&](){});

to unambiguously bind to the reference_closure; using reference_closure can be an order of magnitude faster than using function.

(See also issue 751.)

Proposed resolution (July, 2009)

See document PL22.16/09-0117 = WG21 N2927. (See also document PL22.16/09-0035 = WG21 N2845, which partially addressed this issue by the removal of std::reference_clossure.)