lambda的遗传是否由标准保证?

Vin*_*ent 16 c++ lambda standards final language-lawyer

在C++标准中,闭包类型定义如下:

[expr.prim.lambda.closure] lambda表达式的类型(也是闭包对象的类型)是一个唯一的,未命名的非联合类类型,称为闭包类型,其属性如下所述.[...]

该标准似乎并未定义未命名的非联合类类型是否为final.将lambdas实现为最终类的编译器是否符合标准,或者我们是否可以保证可以从lambdas继承?

问题不在于从lambdas继承是否有用:它是有用的.问题是标准是否提供此保证.

bol*_*lov 18

是的,封闭类型不能是最终的.至少这是我的解释.

§8.1.5.1闭包类型[expr.prim.lambda.closure]

实现可以定义闭包类型与下面描述的不同,前提是这不会改变程序的可观察行为,只需更改:

  • ... [不适用]

该标准然后没有将闭包类型描述为最终的.使其成为最终将改变可观察的行为,因此封闭类型不能是最终的.

关于可观察的行为.考虑一下:

auto l = []{};
return std::is_final_v<decltype(l)>;
Run Code Online (Sandbox Code Playgroud)

使闭包类型最终将明确修改有效程序的可观察行为.


至于用例,它实际上可以是一个非常有用的功能:

template <class... Fs> struct Overload : Fs ...
{
    using Fs::operator()...;
};

template <class... Fs> Overload(Fs...) -> Overload<Fs...>;

auto test()
{
    Overload f = {[] (int a) { return a * 100; },
                  [] (int a, int b) { return a + b;}};

    return f(1) + f(2, 3); // 105
}
Run Code Online (Sandbox Code Playgroud)

godbolt看到它的行动


感谢hvd和rakete1111在评论中的讨论和反馈.

  • @hvd你能举出标准禁止封闭类型最终的位置吗? (2认同)
  • @Vincent"[...]提供这不会改变程序的可观察行为,只需更改[...]"位:使闭包类型最终会改变可观察行为.我不能完全确定的是,那里是否有未指明的方面,以及以下段落是否应涵盖在内. (2认同)