C ++拉姆达表达式可以扔?(Can C++ lambda-expression throw?)

2019-10-19 17:29发布

我找不到关于构建闭包对象时抛出异常事情。

这是无视,这可以表达载体的拷贝构造期间抛出:

auto v = std::vector<int>(1000000);
[v]{};

但是,关于这样的空或“参照”捕获列表中的内容:

[&]{};

现在我来说只有大约施工封闭的对象。 呼叫不感兴趣。

我读5.1.2 Lambda expressions [expr.prim.lambda]但发现没有什么特别的抛出异常的保证。

Answer 1:

根据标准( n3337草案 ),§5.1.2/ 3:

类型的λ-表达的(也是封闭的对象的类型)是一个唯一的,不连无名类类型 - 称为闭合类型 - 其特性如下所述。 这个类型不是汇总(8.5.1)。 封闭件类型是在最小的块范围,类范围,或命名空间中包含对应λ-表达范围中声明。

概括地说,一个lambda表达式最终实例化一个匿名类型(仅已知的编译器),包含存储在捕获列表中指示的值的成员变量。 所以,想象一下,你看到这个样子的类:

class __IgnoreMe__
{
    std::vector<int>& _v;

public:
    __IgnoreMe__(std::vector<int>& v)
        : _v(v)
    {
    }

    void operator()()
    {
    }
};

注:这是不完全由编译器创建的类的外观标准规定了用于生成的类,我已经离开了为简洁起见具体要求。)

现在想象你实例化类是这样的:

auto v = std::vector<int>(1000000);
auto my_lambda = __IgnoreMe__(v);

的实例可以my_lambda抛出一个异常? 如果是这样,则关闭对象的构造可以抛出异常。 (这不可能,在这种情况下)。

至于提供无抛出保证,该标准不要求编译器考虑到这一点,但它并不妨碍他们从任一做。 的§5.1.2/ 3的状态结束:

实现可以定义不同于在以下说明的前提是不能改变不是通过改变其他程序的观察行为的闭合类型:

- 封闭类型的大小和/或对准,

- 闭合类型是否是平凡能够复制(第9节),

- 闭合类型是否是一个标准的布局类(第9节),或

- 闭合类型是否是一个POD类(第9节)。



文章来源: Can C++ lambda-expression throw?