在构造闭包对象时,我找不到任何关于抛出异常的内容。
这个表达式可以在向量的复制构造期间抛出:
auto v = std::vector<int>(1000000);
[v]{};
但是空的或“按引用”捕获列表如下:
[&]{};
我现在只说关闭对象的构造。打电话并不有趣。
我读过5.1.2 Lambda expressions [expr.prim.lambda]
,但没有发现关于无保证的特别之处。
答案 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条)。