user9639921
user9639921

Reputation: 401

Why are some functionalities inside a bigger function written as lambdas in C++?

I was under the impression that writing crisp functions that does just one thing is better than writing a relatively larger function that does more than one thing and enclosing that as a lambda?

Upvotes: 1

Views: 132

Answers (2)

YePhIcK
YePhIcK

Reputation: 5866

Quite often, especially in algorithms in a standard library, there's a need to provide a short function. Some of the obvious examples of that are super-short functions that "tell" the std::sort how to properly compare two values (say you are sorting a vector of your own type with multiple keys and you want to sort "this time" by one of those keys).

In these cases it used to be required (pre-C++11) to write that short function as a named function. Doing so would generally pollute the name space and to solve this - lambdas were introduced.

This doesn't violate the "one function - one thing" principle as the lambda in this case is just a supporting shortcut for an in-place short code that would otherwise need be put into a standalone named function.

Upvotes: 1

Caleth
Caleth

Reputation: 63402

When thinking about the length of a function, it's useful to consider the body of any lambdas inside it to be not part of the length. Imagine to yourself they have been extracted to elsewhere and just referenced.

Having said that, let's distinguish two cases of lambdas:

Capturing lambdas

Virtually required to be defined in-function, as the alternative is creating a class type with an appropriate operator() and some initialiser. Values of such function types are not really useful outside of the function using them. This is both more boilerplate and less localised, there is no upside.

E.g. given

struct Compound
{
    int interesting_member;
    std::string uninteresting_member;
};

If you want to find a specific Compound in a std::vector<Compound> based on only the value of interesting_member, you can implement it either

struct CompoundFinder
{
    bool operator(const Compound & item) { return item.interesting_member == needle; }
    int needle;
}

std::vector<Compound>::iterator find_by_interesting(int needle, std::vector<Compound> & haystack)
{
    return std::find_if(haystack.begin(), haystack.end(), CompoundFinder{ needle });
}

Or with a capturing lambda

std::vector<Compound>::iterator find_by_interesting(int needle, std::vector<Compound> & haystack)
{
    return std::find_if(haystack.begin(), haystack.end(), 
        [needle](const Compound & item) 
        { return item.interesting_member == needle; });
}

Non-Capturing lambdas

Here it is less clear cut. If you only need a particular function once, it can be simpler to definition a lambda rather than add a name to the enclosing scope that performs the same task.

Upvotes: 0

Related Questions