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


1468. typeid, overload resolution, and implicit lambda capture

Section: 7.5.5.3  [expr.prim.lambda.capture]     Status: CD5     Submitter: Doug Gregor     Date: 2012-02-08

[Resolved by the adoption of P0588R1 at the November, 2017 meeting.]

According to 7.5.5 [expr.prim.lambda] paragraph 11, a variable is implicitly captured if it is odr-used. In the following example,

  struct P {
   virtual ~P();
  };

  P &f(int&);
  int f(const int&);

  void g(int x) {
   [=] {
    typeid(f(x));
   };
  }

x is only odr-used if the operand of typeid is a polymorphic lvalue; otherwise, the operand is unevaluated (7.6.1.8 [expr.typeid] paragraphs 2-3). Whether the operand is a polymorphic lvalue depends on overload resolution in this case, which depends on whether x is captured or not: if x is captured, since the lambda is not mutable, the type of x in the body of the lambda is const int, while if it is not captured, it is just int. However, the const int version of f returns int and the int version of f returns a polymorphic lvalue, leading to a conundrum: x is only captured if it is not captured, and vice versa.

Notes from the October, 2012 meeting:

The approach favored by CWG was to specify that the operand of typeid is considered to be odr-used for the purpose of determining capture.