简体   繁体   中英

Generic lambdas: syntactic sugar or not?

Do C++14 generic lambdas bring a real improvement to the language or they are a kind of syntactic sugar? Whether there are some situations where

[](auto param1, auto param2, /* ... */ auto paramN)
{
    return /* ... */;
}

cannot be replaced with

template <typename Type1, typename Type2, /* ... */ typename TypeN>
auto foo(Type1&& param1, Type2&& param2, /* ... */ TypeN&& paramN)
{
    return  /* ... */;
}

or

struct bar
{
    template <typename Type1, typename Type2, /* ... */ typename TypeN>
    auto operator()(Type1&& param1, Type2&& param2, /* ... */ TypeN&& paramN)
    {
        return  /* ... */;
    }
};

?


@Kerrek SB provided very interesting links in the comments which illustrate the power of generic lambdas:

For the non-generic lambda expressions of C++11, there is a somewhat straightforward translation that can be performed:

void foo()
{
    int i = 42; int j = 22;
    auto f = [i, &j](int k) { return i + j + k };
    // proceed to use f
 }

For instance:

void foo()
{
    int i = 42; int j = 22;
    struct {
        int i; int& j;
        // can't deduce return type
        int operator()(int k) const
        { return i + j + k; }
    } f { i, j };
    // proceed to use f
}

For the generic lambda expressions of C++14, it's not so straightforward. Suppose this time we're using auto f = [i, &j](auto k) { return i + j + k; } auto f = [i, &j](auto k) { return i + j + k; } . Then we must produce the following call operator:

template<typename T>
auto operator()(T k) const { return i + j + k; }

The problem is that we cannot define a template at function scope (a restriction also known as no local templates ). So we must move out the closure type definition out of the enclosing function to namespace scope (giving it a name in the process), then use closure_type f { i, j }; . Incidentally this means we have to give the class and its operator some form of linkage, whereas function local definitions have no linkage.

So in a sense, generic lambda expressions give us a limited version of local function templates.

On Lambdas in general:

Some consider this "really neat!"; others see it as a way to write dangerously obscure code. IMO, both are right. --- Bjarne Stroustrup

I think it is a question of how you use lambda. As small local closure function, that you use to improve handling with functions, which take function objects as parameters (like std::sort ), I haven't actually seen an example, where generic lambdas would add any benefit.

If you use them to code haskell-like in C++, then it will add some benefit, but I have seen too many examples of code, where object lifetime was at least partially ignored. So I don't think, that it will add a benefit.

Let me explain that a bit:

void foo(std::vector<int>& v)
{
    std::sort(v.begin(), v.end(), [](int i, int j) { return (i < j); });
}

This is a real improvement, but registering a callback, that will be called later and possibly in another thread:

void C::foo()
{
    registerLazyMultithreadedCallback([=this]() { return this; });
}

This will make things complicated, because you have to ensure, that the object you return is valid. This could lead into ridiculous situations (eg calling short time after destruction). My experience is, that the coder will think twice before writing such a construct without lambda.

So if you use them only locally as helper functions, there is no need for generics, because all types are clear.

I guess I am one of those, who think that you can write dangerous obscure code with lambda.

Do C++14 generic lambdas bring a real improvement to the language

Yes.

or they are a kind of syntactic sugar?

Yes.

You seem to imply that syntactic sugar is not a real improvement to the language. Keep in mind that the language itself is syntactic sugar. You could be writing everything in machine code :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM