Movatterモバイル変換


[0]ホーム

URL:


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

2025-04-13


2300. Lambdas in multiple definitions

Section:6.3  [basic.def.odr]    Status:CD5    Submitter:Robert Haberlach    Date:2016-04-11

[Accepted as a DR at the July, 2019 meeting.]

A lambda expression in two translation units has distinct closuretypes, because each such expression's type is unique within the program.This results in an issue with the ODR, which requires that the definitionsof an entity are identical. For example, if

  template <int> void f() {std::function<void()> f = []{};}

appears in two translation units, different specializations offunction's constructor template are called, which violates6.3 [basic.def.odr] bullet 6.4.

Issue 765 dealt with a similar problemfor inline functions, but the issue still remains for templates.

Proposed resolution, April, 2019:

Change 6.3 [basic.def.odr] paragraph 12 as follows:

...Given such an entity namedD defined in morethan one translation unit, then

IfD is a template and is defined in more thanone translation unit, then the preceding requirements shallapply both to names from the template's enclosing scope usedin the template definition (_N4868_.13.8.4 [temp.nondep]),and also to dependent names at the point of instantiation(13.8.3 [temp.dep]).If the definitionsofD satisfy all these requirements, then thebehavior is as if there were a single definitionofD.These requirements also apply tocorresponding entities defined within each definition ofD (including the closure typesoflambda-expressions, but excluding entities definedwithin default arguments or defualt template arguments ofeitherD or an entity not defined withinD). For each such entity and forD itself,the behavior is as if there is a single entity with a singledefinition, including in the application of theserequirements to other entities. [Note: Theentity is still declared in multiple translation units, and6.6 [basic.link] still applies to thesedeclarations. In particular,lambda-expressions(7.5.6 [expr.prim.lambda]) appearing in the typeofD may result in the different declarationshaving distinct types, andlambda-expressionsappearng in a default argument ofD may stilldenote different types in different translationunits. —end note] If the definitionsofD do not satisfy these requirements, then thebehavior is undefined.program is ill-formed, no diagnostic required.[Example:

  inline void f(bool cond, void (*p)()) {    if (cond) f(false, []{});  }  inline void g(bool cond, void (*p)() = []{}) {    if (cond) g(false);  }  struct X {    void h(bool cond, void (*p)() = []{}) {      if (cond) h(false);    }  };

If the definition off appears in multipletranslation units, the behavior of the program is as if thereis only one definition off. If the definition ofg appears in multiple translation units, the programis ill-formed (no diagnostic required) because each suchdefinition uses a default argument that refers to a distinctlambda-expression closure type. The definition ofXcan sppear in multiple translation units of a valid program; thelambda-expressions defined within the default argumeht ofX::h within the definition ofX denote thesame closure type in each translation unit. —endexample]




[8]ページ先頭

©2009-2025 Movatter.jp