gpt4 book ai didi

c++ - 无捕获的 lambda 是结构类型吗?

转载 作者:行者123 更新时间:2023-12-03 06:49:43 28 4
gpt4 key购买 nike

P1907R1 ,为 C++20 接受,引入了结构类型,这是非类型模板参数的有效类型。
GCC 和 Clang 都接受以下 C++2a 代码片段:

template<auto v>
constexpr auto identity_v = v;

constexpr auto l1 = [](){};
constexpr auto l2 = identity_v<l1>;
暗示无捕获 lambda 的类型是结构类型。

  • 无捕获 lambda 确实满足其类型成为结构类型的要求吗?
  • 最佳答案

    除非另有明确说明,以下所有标准引用均指 N4861 (March 2020 post-Prague working draft/C++20 DIS) .

    无捕获 lambda 的类型(其闭包类型)是结构类型
    以后,我们将把 lambda 的类型单独称为闭包类型。
    如下面的标准段落所示,无捕获 lambda 的闭包类型:

  • 满足它是文字(类)类型的要求,而且
  • 满足对文字类型的要求,使其成为结构类型,

  • 并且因此可以用作非类型模板参数的类型,例如示例片段
    template<auto v>
    constexpr auto identity_v = v;

    constexpr auto l1 = [](){};
    constexpr auto l2 = identity_v<l1>;

    确实是良构的。

    lambda 的闭包类型是非 union 类类型
    [expr.prim.lambda.closure]/1 管辖[ 重点 矿]

    The type of a lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type, called the closure type, whose properties are described below.


    闭包类型是非 union 类类型。

    无捕获 lambda 的闭包类型是文字(类)类型
    [basic.types]/10 管辖[提取, 重点 矿]

    A type is a literal type if it is:

    • [...]
    • a possibly cv-qualified class type that has all of the following properties:
      • it has a constexpr destructor ([dcl.constexpr]),
      • it is either a closure type ([expr.prim.lambda.closure]), an aggregate type ([dcl.init.aggr]), or has at least one constexprconstructor or constructor template (possibly inherited from a baseclass) that is not a copy or move constructor,
      • if it is a union, at least one of its non-static data members is of non-volatile literal type, and
      • if it is not a union, all of its non-static data members and base classes are of non-volatile literal types.

    闭包类型是文字类型,如果
  • 有一个 constexpr 析构函数,如果
  • 它的所有非静态数据成员都是非 volatile 文字类型。

  • 无捕获 lambda 的闭包类型没有非静态数据成员,因此满足后一个要求。前者呢,一个 constexpr 析构函数?
    隐式生成的 constexpr 析构函数
    [expr.prim.lambda.closure]/14 管辖

    The closure type associated with a lambda-expression has an implicitly-declared destructor ([class.dtor]).


    闭包类型的析构函数是隐式声明的。此外, [/dcl.fct.def.default]/5描述 [提取物, 重点 矿]

    Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them ([class.ctor], [class.dtor], [class.copy.ctor], [class.copy.assign]), [...]


    集体术语默认函数还包括隐式声明的析构函数。
    最后, [class.dtor]/9

    A defaulted destructor is a constexpr destructor if it satisfies the requirements for a constexpr destructor ([dcl.constexpr]).


    描述默认的析构函数是 constexpr 析构函数,如果它们满足 [dcl.constexpr] 的要求,特别是 [dcl.constexpr]/3[dcl.constexpr]/5 [提取, 重点 矿]

    [dcl.constexpr]/3 The definition of a constexpr function shall satisfy the following requirements:

    • [...]
    • if the function is a constructor or destructor, its class shall not have any virtual base classes;
    • [...]

    [dcl.constexpr]/5 The definition of a constexpr destructor whose function-body is not = delete shall additionally satisfy the following requirement:

    • for every subobject of class type or (possibly multi-dimensional) array thereof, that class type shall have a constexpr destructor.

    所有这些都满足无捕获 lambda 的闭包类型(没有基类,也没有子对象;后者见 [intro.object]/2)。
    因此,无捕获 lambda 的闭包类型是文字类型。

    无捕获 lambda 的闭包类型是结构类型
    根据 [temp.param]/6[temp.param]/7 [提取, 重点 矿]

    [temp.param]/6 A non-type template-parameter shall have one of the following (possibly cv-qualified) types:

    • a structural type (see below),
    • [...]

    [temp.param]/7

    A structural type is one of the following:

    • a scalar type, or
    • an lvalue reference type, or
    • a literal class type with the following properties:
      • all base classes and non-static data members are public and non-mutable and
      • the types of all bases classes and non-static data members are structural types or (possibly multi-dimensional) array thereof.

    如果文字类类型没有基类和非静态数据成员,那么它就是结构类型。这两者都适用于无捕获 lambda,因此,无捕获 lambda 的闭包类型是结构类型。

    关于允许 lambda 的闭包类型为文字类型的初衷的一些说明
    N4487提议允许某些 lambda 表达式和对某些闭包对象的操作出现在常量表达式中,并包含一个专门的部分,用于讨论闭包类型是文字类型的主题:

    The closure object should be a literal type if the type of each of its data­ members is a literal type.

    A closure type in C++14 can never be a literal type – even if all itsdata members are literal types – because it lacks a constexprconstructor that is not a copy or move constructor. If such a closuretype was allowed to have an implicitly defined default constructor itwould be constexpr, making it a literal type. But, because closuretypes, by definition, must have their default constructors deleted,the implementation is prohibited from implicitly defining one. [...]


    P0170R1包含来自 N4487 的核心措辞,已被 C++17 接受并实现。
    然而此时(C++14和C++17),析构函数不能是constexpr,因此自然不要求字面类型有constexpr析构函数; [basic.types]/10.5.1在 N4140 (C++14) 以及 [basic.types]/10.5.1 中在 N4659 (C++17) 中,相反要求析构函数是微不足道的:

    A type is a literal type if it is:

    • [...]
    • a class type (Clause [class]) that has all of the following properties:
      • it has a trivial destructor,
      • [...]

    P1907R1 ,为 C++20 接受,扩展了模板参数对象具有不断销毁的要求; [temp.param]/8 [ 重点 矿]:

    An id-expression naming a non-type template-parameter of class type T denotes a static storage duration object of type const T, known as a template parameter object, whose value is that of the corresponding template argument after it has been converted to the type of the template-parameter. All such template parameters in the program of the same type with the same value denote the same template parameter object. [...] A template parameter object shall have constant destruction.


    和, P0784R7 ,也被 C++20 接受,特别是引入了 constexpr 析构,包括对类型为字面类型的要求的更新;在论文的早期版本中特别描述, P0784R1 :

    The proposed rules for constexpr destructors are:

    • [...]
    • A literal type requires a constexpr destructor (previously, the stronger requirement of a trivial destructor was made)

    关于c++ - 无捕获的 lambda 是结构类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64461199/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com