可以C ++ lambda-expression抛出吗?

时间:2014-03-28 17:05:24

标签: c++ exception c++11 lambda

在构造闭包对象时,我找不到任何关于抛出异常的内容。

这个表达式可以在向量的复制构造期间抛出:

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

但是空的或“按引用”捕获列表如下:

[&]{};

我现在只说关闭对象的构造。打电话并不有趣。

我读过5.1.2 Lambda expressions [expr.prim.lambda],但没有发现关于无保证的特别之处。

1 个答案:

答案 0 :(得分:4)

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

  

lambda表达式的类型(也是闭包对象的类型)是一个独特的,未命名的不愈合   class type - 称为闭包类型 - 其属性如下所述。这个类类型不是   总计(8.5.1)。闭包类型在最小的块作用域,类作用域或命名空间中声明   包含相应lambda表达式的范围。

简而言之,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的实例化是否可以抛出异常?如果是这样,那么闭包对象的构造可以抛出异常。 (在这种情况下,它不能。)

至于提供nothrow保证,标准不要求编译器对此进行说明,但它不会阻止他们这样做。 §5.1.2/ 3的结尾说明:

  

实现可以定义闭包   类型不同于下面描述的类型,只要这不会改变可观察到的行为   除了改变以外的程序:

     

- 闭包类型的大小和/或对齐方式

     

- 闭包类型是否可以轻易复制(第9条),

     

- 闭包类型是标准布局类(第9条)还是

     

- 闭包类型是否为POD类(第9条)。