c++ lambda表达式能抛出吗?

Can C++ lambda-expression throw?

本文关键字:lambda 表达式 c++      更新时间:2023-10-16

我找不到任何关于在构造闭包对象期间抛出异常的信息。

没有注意到这个表达式在vector的复制构造过程中可能抛出:

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

但是像这样的空或"引用"捕获列表呢?

[&]{};

我现在只讨论闭包对象的构造。打电话没什么意思。

我读了5.1.2 Lambda expressions [expr.prim.lambda],但是没有发现nothrow保证有什么特别之处

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

lambda表达式的类型(也是闭包对象的类型)是唯一的、未命名的非联合类型类类型-称为闭包类型-其属性将在下面描述。这个类类型不是一个集合(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条)。