c++ - 标准是否保证了 lambda 的可继承性?

标签 c++ lambda language-lawyer standards final

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

[expr.prim.lambda.closure] 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 类类型是否是最终的。将 lambdas 实现为 final 类的编译器是否符合标准,或者我们是否可以保证可以从 lambdas 继承?

问题不在于继承 lambdas 是否有用:它是有用的。问题是标准是否提供了这种保证。

最佳答案

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

§8.1.5.1 Closure types [expr.prim.lambda.closure]

An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing:

  • ... [does not apply]

标准没有将闭包类型描述为最终的。将其设为 final 会改变可观察的行为,因此闭包类型不能是 final。

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

auto l = []{};
return std::is_final_v<decltype(l)>;

将闭包类型设为 final 显然会修改有效程序的可观察行为。


对于一个用例,它实际上可以是一个非常有用的特性:

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
}

godbolt 上查看它的实际应用


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

关于c++ - 标准是否保证了 lambda 的可继承性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49704835/

相关文章:

c++ - 当函数模板专门用于不同的命名空间时,GCC 和 clang 不同意

c++ - qglwidget 如何与主窗口中的其他小部件交互

c++ - 64 位系统上的 32 位 Com 服务器

c++ - 在捕获 `this->` 的 lambda 中使用 `this`

java - 如何使用 Java 流将两个数组合并到一个映射中?

c++ - 如何检查 int 变量是否包含合法(非陷阱表示)值?

c++ - 在模板类中重载 operator=

c++ - 扩展 QStandardItem 不返回数据

python - return 语句中的 Lambda 给出两个输出,但如果不使用 print 则只有一个输出

rust - Rust的确切自动引用规则是什么?