In this case, there isnt much point in writing a lambda. The only difference is the scope of printVector. The lambda is local to main, the free function is visible globally (at least here). Most of the time when its about code reuse, you will want to use a (free) function. So this printVector should almost certainly be a function. Lambdas however are really useful when you need to quickly define an "ad hoc" function that does something. Usually this is the case when using standard algorithms: struct Person { std::string name; std::chrono::year_month_weekday dob; }; int main() { std::vector people; constexpr auto by_name_desc = []( const auto& p1, const auto& p2){ return p1.name < p2.name; }; std::sort( people.begin(), people.end(), by_name_desc ); } Here we want to sort our vector of Persons by name. For this, we need to give std::sort a predicate that establishes an ordering. We could also write a free function. However, such a function would have to be defined outside of main. You can imagine the clutter it would cause if you needed to define 20 additional functions elsewhere. Further, the lambda can have templated arguments, so we can write a generic sorter that doesnt directly take Person objects. Of course if you wanted to have this ordering availible in other places, the defining a static member function for Person instead of a bunch of local lambdas may be preferable. Note that C++20 added range-based versions of the algorithms, which allow you to pass relation and a projector seperately, elliminating the need for a lambda in this particular case: std::ranges::sort( people, std::less{}, &Person::name ); Answer from IyeOnline on reddit.com
🌐
Hackaday
hackaday.com › 2019 › 09 › 11 › lambdas-for-c-sort-of
Lambdas For C — Sort Of | Hackaday
November 2, 2023 - Friends don’t let friends use compiler specific language extensions… (except when developing for bare metal!) ... No, it shouldn’t be. Some things are better kept implementation specific. ... Oh geez. C was not intended to have this level of abstraction. C++, Python, etc have good reasons to have lambda functions (namespace pollution, closures, etc).
🌐
Reddit
reddit.com › r/cpp_questions › why use lambdas
r/cpp_questions on Reddit: Why use lambdas
February 25, 2024 -

Hey all, long time lurker. I've seen a lot of code where I work which use lambdas. I couldn't understand why they are used (trying hard to learn how to write them). So an example

```

int main() {

std::vector < int > myVector = { 1,2,3,4,5};

printVector = [](const std::vector < int > & vec) {

std::cout << "Vector Elements: ";

for (const auto & element: vec) {

std::cout << element << " ";

}

std::cout << std::endl;

};

printVector(myVector);

return 0;

}

```

vs

```

void printVector(const std::vector < int > & myVector) {

std::cout << "Vector Elements: ";

for (const auto & element: myVector) {

std::cout << element << " ";

}

}

int main() {

std::vector < int > myVector = {1, 2, 3, 4, 5};

{

std::cout << "Vector Elements: ";

for (const auto & element: vec) {

std::cout << element << " ";

}

std::cout << std::endl;

};

```

Is there any time I should prefer 1 over another. I prefer functions as I've used them longer.

Top answer
1 of 11
25
In this case, there isnt much point in writing a lambda. The only difference is the scope of printVector. The lambda is local to main, the free function is visible globally (at least here). Most of the time when its about code reuse, you will want to use a (free) function. So this printVector should almost certainly be a function. Lambdas however are really useful when you need to quickly define an "ad hoc" function that does something. Usually this is the case when using standard algorithms: struct Person { std::string name; std::chrono::year_month_weekday dob; }; int main() { std::vector people; constexpr auto by_name_desc = []( const auto& p1, const auto& p2){ return p1.name < p2.name; }; std::sort( people.begin(), people.end(), by_name_desc ); } Here we want to sort our vector of Persons by name. For this, we need to give std::sort a predicate that establishes an ordering. We could also write a free function. However, such a function would have to be defined outside of main. You can imagine the clutter it would cause if you needed to define 20 additional functions elsewhere. Further, the lambda can have templated arguments, so we can write a generic sorter that doesnt directly take Person objects. Of course if you wanted to have this ordering availible in other places, the defining a static member function for Person instead of a bunch of local lambdas may be preferable. Note that C++20 added range-based versions of the algorithms, which allow you to pass relation and a projector seperately, elliminating the need for a lambda in this particular case: std::ranges::sort( people, std::less{}, &Person::name );
2 of 11
20
Lambdas is a convenient way to create "function objects" which is often useful when using the algorithm functions. For example, imagine you wanted to sort a list of numbers based on the distance from another number that the user enters. Without using lambdas you could write it like this: #include #include #include #include struct CompareDistanceTo { int k; bool operator()(int a, int b) const { return std::abs(a - k) < std::abs(b - k); } }; int main() { std::vector numbers {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int k; std::cin >> k; std::ranges::sort(numbers, CompareDistanceTo{k}); for (int n : numbers) { std::cout << n << '\n'; } } By using a lambda you can simplify it to: #include #include #include #include int main() { std::vector numbers {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int k; std::cin >> k; std::ranges::sort(numbers, [&](int a, int b) { return std::abs(a - k) < std::abs(b - k); }); for (int n : numbers) { std::cout << n << '\n'; } }
Top answer
1 of 11
1808

The problem

C++ includes useful generic functions like std::for_each and std::transform, which can be very handy. Unfortunately they can also be quite cumbersome to use, particularly if the functor you would like to apply is unique to the particular function.

#include <algorithm>
#include <vector>

namespace {
  struct f {
    void operator()(int) {
      // do something
    }
  };
}

void func(std::vector<int>& v) {
  f f;
  std::for_each(v.begin(), v.end(), f);
}

If you only use f once and in that specific place it seems overkill to be writing a whole class just to do something trivial and one off.

In C++03 you might be tempted to write something like the following, to keep the functor local:

void func2(std::vector<int>& v) {
  struct {
    void operator()(int) {
       // do something
    }
  } f;
  std::for_each(v.begin(), v.end(), f);
}

however this is not allowed, f cannot be passed to a template function in C++03.

The new solution

C++11 introduces lambdas allow you to write an inline, anonymous functor to replace the struct f. For small simple examples this can be cleaner to read (it keeps everything in one place) and potentially simpler to maintain, for example in the simplest form:

void func3(std::vector<int>& v) {
  std::for_each(v.begin(), v.end(), [](int) { /* do something here*/ });
}

Lambda functions are just syntactic sugar for anonymous functors.

Return types

In simple cases the return type of the lambda is deduced for you, e.g.:

void func4(std::vector<double>& v) {
  std::transform(v.begin(), v.end(), v.begin(),
                 [](double d) { return d < 0.00001 ? 0 : d; }
                 );
}

however when you start to write more complex lambdas you will quickly encounter cases where the return type cannot be deduced by the compiler, e.g.:

void func4(std::vector<double>& v) {
    std::transform(v.begin(), v.end(), v.begin(),
        [](double d) {
            if (d < 0.0001) {
                return 0;
            } else {
                return d;
            }
        });
}

To resolve this you are allowed to explicitly specify a return type for a lambda function, using -> T:

void func4(std::vector<double>& v) {
    std::transform(v.begin(), v.end(), v.begin(),
        [](double d) -> double {
            if (d < 0.0001) {
                return 0;
            } else {
                return d;
            }
        });
}

"Capturing" variables

So far we've not used anything other than what was passed to the lambda within it, but we can also use other variables, within the lambda. If you want to access other variables you can use the capture clause (the [] of the expression), which has so far been unused in these examples, e.g.:

void func5(std::vector<double>& v, const double& epsilon) {
    std::transform(v.begin(), v.end(), v.begin(),
        epsilon -> double {
            if (d < epsilon) {
                return 0;
            } else {
                return d;
            }
        });
}

You can capture by both reference and value, which you can specify using & and = respectively:

  • [&epsilon, zeta] captures epsilon by reference and zeta by value
  • [&] captures all variables used in the lambda by reference
  • [=] captures all variables used in the lambda by value
  • [&, epsilon] captures all variables used in the lambda by reference but captures epsilon by value
  • [=, &epsilon] captures all variables used in the lambda by value but captures epsilon by reference

The generated operator() is const by default, with the implication that captures will be const when you access them by default. This has the effect that each call with the same input would produce the same result, however you can mark the lambda as mutable to request that the operator() that is produced is not const.

2 of 11
955

What is a lambda expression?

The C++ concept of a lambda expression originates in the lambda calculus and functional programming. A lambda is an unnamed function that is useful (in actual programming, not theory) for short snippets of code that are impossible to reuse and are not worth naming.

In C++, the minimal lambda expression looks like:

[]{} // lambda with no parameters that does nothing 

[] is the capture list and {} the function body.

The full syntax for a lambda-expression, including attributes, noexcept/throw-specifications, requires-clauses, etc. is more complex.

The capture list

The capture list defines what from the outside of the lambda should be available inside the function body and how. It can be either:

  1. a value: [x]
  2. a reference [&x]
  3. any variable currently in scope by reference [&]
  4. same as 3, but by value [=]
  5. capturing this and making member functions callable within the lambda [this]

You can mix any of the above in a comma separated list [x, &y].

Init-captures (C++14)

An element of the capture list can now be initialized with =, which is called init-capture. This allows renaming of variables and to capture by moving. An example taken from the standard:

int x = 4;
auto y = [&r = x, x = x+1]()->int {
            r += 2;
            return x+2;
         }();  // Updates ::x to 6, and initializes y to 7.

and one taken from Wikipedia showing how to capture with std::move:

auto ptr = std::make_unique<int>(10); // See below for std::make_unique
auto lambda = [ptr = std::move(ptr)] {return *ptr;};

The template parameters (C++20)

Since C++20, lambda expressions can have a template-parameter-list:

[]<int N>() {};

Such a generic lambda is like a non-template struct with a call operator template:

struct __lambda {
    template <int N> void operator()() const {}
};

The parameter list

The parameter-declaration-clause is the same as in any other C++ function. It can be omitted completely when there are no parameters, meaning that [](){} is equivalent to []{}.

Generic Lambdas (C++14)

Lambdas with an auto parameter are generic lambdas. auto would be equivalent to T here if T were a type template argument somewhere in the surrounding scope):

[](auto x, auto y) { return x + y; }

This works just like a C++20 abbreviated function template:

struct __lambda {
    // C++20 equivalent
    void operator()(auto x, auto y) const { return x + y; }
    // pre-C++20 equivalent
    template <typename T, typename U>
    void operator()(T x, U y) const { return x + y; }
};

Return type (possibly deduced)

If a lambda has only one return statement, the return type can be omitted and has the implicit type of decltype(return_statement).

The return type can also be provided explicitly using trailing return type syntax:

[](int x) -> int { return x; }

Improved Return Type Deduction (C++14)

C++14 allows deduced return types for every function and does not restrict it to functions of the form return expression;. This is also extended to lambdas. By default, the return type of a lambda is deduced as if its return type was declared auto.

Mutable lambda (C++14)

If a lambda is marked mutable (e.g. []() mutable { }) it is allowed to mutate the values that have been captured by value.

mutable means that the call operator of the lambda's type does not have a const qualifier.

The function body

A block-statement will be executed when the lambda is actually called. This becomes the body of the call operator.

Use cases

The library defined by the ISO standard benefits heavily from lambdas and raises the usability several bars as now users don't have to clutter their code with small functors in some accessible scope.

🌐
Quora
quora.com › How-do-we-write-and-use-lambda-functions-in-pure-C-indirectly-instead-of-C
How do we write and use lambda functions in pure C indirectly instead of C++? - Quora
Answer (1 of 5): https://en.wikipedia.org/wiki/Anonymous_function#C_(non-standard_extension) > C (non-standard extension)[edit] The anonymous function is not supported by standard C programming language, but supported by some C dialects, such as GCC[52] and Clang. GCC[edit] GNU Compiler Colle...
🌐
Built In
builtin.com › software-engineering-perspectives › c-plus-plus-lambda
C++ Lambda Expressions Explained | Built In
At its core, a lambda behaves like a functor with an overloaded operator(). In C++, use a lambda expression when you want to reduce boilerplate code, improve readability or define a function inline — especially for callbacks and STL algorithms.
Top answer
1 of 2
10

This behavior seems to be specfic to newer versions of Clang, and is a language extension called "blocks".

The Wikipedia article on C "blocks" also provides information which supports this claim:

Blocks are a non-standard extension added by Apple Inc. to Clang's implementations of the C, C++, and Objective-C programming languages that uses a lambda expression-like syntax to create closures within these languages. Blocks are supported for programs developed for Mac OS X 10.6+ and iOS 4.0+, although third-party runtimes allow use on Mac OS X 10.5 and iOS 2.2+ and non-Apple systems.

Emphasis above is mine. On Clang's language extension page, under the "Block type" section, it gives a brief overview of what the Block type is:

Like function types, the Block type is a pair consisting of a result value type and a list of parameter types very similar to a function type. Blocks are intended to be used much like functions with the key distinction being that in addition to executable code they also contain various variable bindings to automatic (stack) or managed (heap) memory.

GCC also has something similar to blocks called lexically scoped nested functions. However, there are some key differences also note in the Wikipedia articles on C blocks:

Blocks bear a superficial resemblance to GCC's extension of C to support lexically scoped nested functions. However, GCC's nested functions, unlike blocks, must not be called after the containing scope has exited, as that would result in undefined behavior.

GCC-style nested functions also require dynamic creation of executable thunks when taking the address of the nested function. [...].

Emphasis above is mine.

2 of 2
7

the C standard does not define lambdas at all but the implementations can add extensions.

Gcc also added an extension in order for the programming languages that support lambdas with static scope to be able to convert them easily toward C and compile closures directly.

Here is an example of extension of gcc that implements closures.

#include <stdio.h>

int(*mk_counter(int x))(void)
{
    int inside(void) {
        return ++x;
    }
    return inside;
}

int
main() {
    int (*counter)(void)=mk_counter(1);
    int x;
    x=counter();
    x=counter();
    x=counter();
    printf("%d\n", x);
    return 0;
}
🌐
Reddit
reddit.com › r/c_programming › why does c not have lambdas/anonymous function expressions?
r/C_Programming on Reddit: Why does C not have lambdas/anonymous function expressions?
August 7, 2022 -

It would not seem to hard to implement to allow a programmer to use a construct similar to:

int (*add)(int, int) = (int(int x, int y)){return x+y;};

This would simplify code that requires callback functions such as qsort or bsearch or various UI libraries that use callbacks to define, for example, a buttons behavior when pressed. Is there any specific reason they elected not to support this, and require us to define named static functions instead?

Top answer
1 of 7
8
There are two basic ways to implement closures: A custom calling convention: Callers are aware they're calling a closure and so pass the closure context to the callee, perhaps as a hidden argument. Closures are nearly always implemented this way, including in C++. For C, as a lingua franca platforms would need to define this calling convention / ABI so that different implementers could all each others closures just as they can call each others functions. Since this doesn't exist, closures in language implementations using this approach are incompatible with C interop (ex. can't turn a C++ closure into a function pointer). Build a trampoline by allocating a little bit of executable memory, essentially like using a small JIT compiler. Callers do not need to be aware they're calling a closure, and a plain C calling convention is sufficient. GNU C closures are implemented this way, as are CPython's ctypes callbacks. However, frequently allocating executable memory requires significant trade-offs in performance or security. It may not even be possible on some platforms. This is also an implicit allocation — which is not in the spirit of C — and someone has to manage its lifetime. (GNU C manages it by using an automatic allocation.) Unless you're willing to make the trade-offs in the second approach — which is available to you if you use GCC — neither fits C well.
2 of 7
6
Why are people obsessed with making C like python or whatever language they learned first? It's like asking why my bicycle only has two wheels, when your red wagon has four.
🌐
Quora
cstdspace.quora.com › How-do-we-write-and-use-lambda-functions-in-pure-C-indirectly-instead-of-C
How do we write and use lambda functions in pure C indirectly instead of C++? - C Programmers - Quora
Answer (1 of 3): There aren’t any lambdas in C, so you can’t. You can create a context structure, populate it, and give it as an argument to a callback function, but the syntax is grotty and it is not nicely handled for things that take callbacks don’t have a void* argument for that context.
Find elsewhere
🌐
Medium
madhawapolkotuwa.medium.com › mastering-lambda-functions-in-c-a-complete-guide-with-practical-examples-e2cc3f10dfce
Mastering Lambda Functions in C++: A Complete Guide with Practical Examples | by Madhawa Polkotuwa | Medium
November 1, 2024 - Lambda functions in C++ are a powerful ... operations. They’re commonly used in functional programming, sorting, event handling, and other areas where small, flexible functions are needed....
🌐
Wikipedia
en.wikipedia.org › wiki › Anonymous_function
Anonymous function - Wikipedia
February 18, 2026 - The following example binds the variable "threshold" within an anonymous function that compares input values to this threshold. def comp(threshold: int) -> Callable[[int], bool]: return lambda x: x < threshold · This can be used as a sort of generator of comparison functions:
🌐
Cprogramming.com
cprogramming.com › c++11 › c++11-lambda-closures.html
C++11 - Lambda Closures, the Definitive Guide - Cprogramming.com
How to begin Get the book · C tutorial C++ tutorial Game programming Graphics programming Algorithms More tutorials
🌐
C++ Stories
cppstories.com › 2020 › 05 › lambdasadvantages.html
5 Advantages of C++ Lambda Expressions and How They Make Your Code Better - C++ Stories
In most cases, it’s far easier to use lambdas. I bet you can list a lot of examples from your projects where applying lambda expressions made code much cleaner and easier to read. Regarding the readability, we also have another part: locality. In C++03, you had to create functions or functors that could be far away from the place where you passed them as callable objects.
🌐
DEV Community
dev.to › sandordargo › lambda-expressions-in-c-4pj4
Lambda Expressions in C++ - DEV Community
September 4, 2020 - They are small snippets of code that provide a better readability in most cases if they are not hidden into an enclosing class. By the way, in C++, those enclosing classes would be called functors or function objects.
🌐
LinkedIn
linkedin.com › pulse › lamda-unction-c-amit-nadiger
Lamda function in C++
June 18, 2023 - The capture clause is optional and can be omitted if the lambda function does not use any variables from the enclosing scope. Keep the following in mind when you are using this syntax for the [Capture Clause ]: [] it means that you will not provide anything to lambda.
🌐
Reddit
reddit.com › r/c_programming › simple lambda like functions in c
r/C_Programming on Reddit: simple lambda like functions in C
March 12, 2024 -

I was diving in reddit and I found the following post

I thought: maybe it is possible to do something similar in C with macros or something along those lines.

After some research, I found the following topic on GCC manual:
Statements and Declarations in Expressions

Well, with this construction, it's possible to instruct the compiler to define a function and call it in place, like we can do with lambdas. Look the example bellow:

#include <stdio.h>
int call_callback(void (*callback)()){
    callback();
}

void foo() {
    printf("foo\n");
}

int main(void) {
    call_callback(foo);
    call_callback(({
        void _() {
            printf("this is a lambda?\n");
        }
        (void (*)())_;
    }));
}

For me, it's very interesting. We encounter many situations and libraries that deal with callback functions, and personally, I often find myself declaring simple functions that are only called once. I believe that in these cases, this construct would work very well.

However, debugging it might be challenging.

🌐
GeeksforGeeks
geeksforgeeks.org › c++ › when-to-use-lambda-expressions-instead-of-functions-in-cpp
When to Use Lambda Expressions Instead of Functions in C++? - GeeksforGeeks
July 23, 2025 - Lambda expressions can capture local variables from their enclosing scope, which isn’t possible with normal functions and it is very useful when the operation depends on some local state.
🌐
GeeksforGeeks
geeksforgeeks.org › c++ › lambda-expression-in-c
Lambda Expression in C++ - GeeksforGeeks
Return Type: Generally, the return-type in lambda expressions is evaluated by the compiler itself and we don’t need to specify it explicitly. However, in some complex cases e.g. conditional statements, the compiler can’t determine the return type and explicit specification is required. A lambda expression can have more power than an ordinary function by having access to variables from the enclosing scope.
Published   5 days ago