Can C ++ Expression Lambda Expressions?

I can't seem to find anything about throwing exceptions during the creation of the closure object.

Ignore what this expression might cause when constructing a copy of the vector:

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

      

But what about empty or "by reference" capture lists:

[&]{};

      

Right now I'm only talking about creating a closure object. The challenge is not interesting.

I read 5.1.2 Lambda expressions [expr.prim.lambda]

but didn't find anything fancy about the nothrow guarantee.

0


source to share


1 answer


According to the standard ( draft n3337 ), ยง5.1.2 / 3:

The type of a lambda expression (which is also the type of a closure object) is a unique, unnamed, non-rooted type of a class - called a closure type - whose properties are described below. This class type is not a collection (8.5.1). A closure type is declared in the smallest block scope, class, or namespace that contains the corresponding lambda expression.

In a nutshell, the lambda expression ultimately creates an anonymous type (known only to the compiler) containing member variables that retain the values โ€‹โ€‹specified in the capture list. So, imagine you saw a class that looked like this:

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

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

    void operator()()
    {
    }
};

      

( Note: this is not exactly what a compiler-generated class looks like. The standard has specific requirements for generated classes that I forgot about for brevity.)



Now, imagine that you are instantiating this class like this:

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

      

Can an instance my_lambda

throw an exception? If so, then constructing the closure object might throw an exception. (In this case, it cannot be.)

As for providing nothrow guarantees, the standard does not require compilers to account for this, but that does not prevent them from doing so. The end of section 5.1.2 / 3 reads:

An implementation can define a closure that is different from what is described below, as long as it does not change the observed behavior of the program, other than changing:

- the size and / or alignment of the closure type,

- whether the closing type is allowed trivially (section 9),

- is the closure type a standard layout class (clause 9) or

- whether the closure type is a POD class (Section 9).

+4


source







All Articles