Movatterモバイル変換


[0]ホーム

URL:


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

2025-12-20


2011. Unclear effect of reference capture of reference

Section:7.5.6.3  [expr.prim.lambda.capture]    Status:C++17    Submitter:Ville Voutilainen    Date:2014-09-28

[Adopted at the February/March, 2017 meeting as document P0613R0.]

The Standard refers to capturing “entities,” and areference is an entity. However, it is not clear what capturing areference by reference would mean. In particular, 7.5.6 [expr.prim.lambda] paragraph 16says,

It is unspecified whether additional unnamed non-static datamembers are declared in the closure type for entitiescaptured by reference.

If a reference captured by reference is not represented by amember, it is hard to see how something like the followingexample could work:

  #include <functional>  #include <iostream>  std::function<void()> make_function(int& x) {    return [&]{ std::cout << x << std::endl; };  }  int main() {    int i = 3;    auto f = make_function(i);    i = 5;    f();  }

Should this be undefined behavior or should it print5?

Proposed resolution (November, 2014) [SUPERSEDED]:

  1. Change 7.5.6 [expr.prim.lambda] paragraph 18 as follows:

  2. Everyid-expression withinthecompound-statement of alambda-expressionthat is an odr-use (6.3 [basic.def.odr]) of an entity captured by copy istransformed into an access to the corresponding unnamed datamember of the closure type. [Note:Anid-expression that is not an odr-use refers to theoriginal entity, never to a member of the closuretype. Furthermore, such anid-expression does notcause the implicit capture of the entity. —endnote] Ifthis is captured, each odr-useofthis is transformed into an access to thecorresponding unnamed data member of the closure type, cast(7.6.3 [expr.cast]) to the type ofthis. [Note: The castensures that the transformed expression is aprvalue. —endnote]Anid-expression withinthecompound-statement of alambda-expressionthat is an odr-use of a reference captured by referencerefers to the entity to which the captured reference isbound and not to the captured reference. [Note: Suchodr-uses are not invalidated by the end of the capturedreference's lifetime. —end note][Example:

      void f(const int*);  void g() {    const int N = 10;    [=] {    int arr[N]; // OK: not an odr-use, refers to automatic variable    f(&N);      // OK: causesN to be captured;&N points to the                // corresponding member of the closure type    };  }  auto h(int &r) {    return [&]() {      ++r;      // Valid afterh returns if the lifetime of the                // object to whichr is bound has not ended    };  }

    end example]

  3. Change 7.5.6 [expr.prim.lambda] paragraph 23 as follows:

  4. [Note: Ifana non-reference entity isimplicitly or explicitly captured by reference, invoking the function calloperator of the correspondinglambda-expression after the lifetimeof the entity has ended is likely to result in undefinedbehavior. —end note]

Proposed resolution (February, 2017):

  1. Change 7.5.6 [expr.prim.lambda] paragraph 17 as follows:

  2. Everyid-expression within thecompound-statement ofalambda-expression that is an odr-use (6.3 [basic.def.odr]) ofan entity captured by copy is transformed into an access to thecorresponding unnamed data member of the closure type. [Note:Anid-expression that is not an odr-use refers to the originalentity, never to a member of the closure type. Furthermore, suchanid-expression does not cause the implicit capture of the entity.—end note] If*this is captured by copy, each odr-useofthis is transformed into a pointer to the corresponding unnameddata member of the closure type, cast (7.6.3 [expr.cast]) to thetype ofthis. [Note: The cast ensures that the transformedexpression is a prvalue. —endnote]Anid-expression within thecompound-statementof alambda-expression that is an odr-use of a reference captured byreference refers to the entity to which the captured reference is bound andnot to the captured reference. [Note: The validity of suchcaptures is determined by the lifetime of the object to which thereference refers, not by the lifetime of the referenceitself. —end note] [Example:

      void f(const int*);  void g() {    const int N = 10;    [=] {    int arr[N]; // OK: not an odr-use, refers to automatic variable    f(&N);      // OK: causesN to be captured;&N points to the                // corresponding member of the closure type    };  }  auto h(int &r) {    return [&] {      ++r;      // Valid afterh returns if the lifetime of the                // object to whichr is bound has not ended    };  }

    end example]

  3. Change 7.5.6 [expr.prim.lambda] paragraph 25 as follows:

  4. [Note: Ifana non-reference entity isimplicitly or explicitly captured by reference, invoking the function calloperator of the correspondinglambda-expression after the lifetimeof the entity has ended is likely to result in undefinedbehavior. —end note]



[8]ページ先頭

©2009-2026 Movatter.jp