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

时间:2018-04-07 07:05:08

标签: c++ lambda language-lawyer standards final

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

  

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

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

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

2 个答案:

答案 0 :(得分:18)

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

  

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

     

实现可以定义闭包类型与不同的类型   如下所述,只要这不会改变可观察的行为   该计划除了改变:

     
      
  • ... [不适用]
  •   

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

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

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

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

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

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在评论中的讨论和反馈。

答案 1 :(得分:0)

final中指定final的效果:

  

如果某个类标有 class-virt-specifier final,并且它在基础中显示为 class-or-decltype -clause ,该程序格式不正确。

也就是说,班级是否是最终的并不重要。只有该类是否使用final说明符标记才有意义。由于闭包类型在源文件中没有任何声明,因此无法将其标记为count all login attempts where date = today'sDate , loginID = userLoginID and booleanLoginSuccess = false ,因此[class] / 3不适用。