Show lambda with parameters are used? How to pass parameters to them?

It works exactly like with any other type of callable object:

#include <iostream>

int main()
{
    auto l = [] (int i) { std::cout << "The answer is " << i; };
    l(42);
}

Also notice, that you do not need to store a lambda in a variable in order to invoke it. The following is an alternative way to rewrite the above program:

#include <iostream>

int main()
{
    [] (int i) { std::cout << "The answer is " << i; } (42);
    //                                                 ^^^^
    //                                 Invoked immediately!
}

The type of a lambda function (the so-called "lambda closure") is defined by the compiler, and is a functor with a call operator whose signature is the one you specify when defining the lambda. Therefore, you call a lambda exactly as you would call a functor (i.e. exactly as you would call a function - or any callable object).

Thus, if you want to assign a lambda to an object, the best practice is to let the compiler deduce its type by using auto. If you do not want or cannot use auto, then you may:

  1. Use function pointers for non-capturing lambdas (capturing lambdas are not convertible to function pointers). In the above case, thus, the following will also work:

    #include <iostream>
    
    int main()
    {
        void (*f)(int) = [] (int i) { std::cout << "The answer is " << i; };
        f(42);
    }
    
  2. Use std::function (this is always possible, even if the lambda is capturing):

    #include <iostream>
    #include <functional>
    
    int main()
    {
        std::function<void(int)> f = [] (int i) 
                                   { std::cout << "The answer is " << i; };
        f(42);
    }
    
Answer from Andy Prowl on Stack Overflow
๐ŸŒ
Medium
kcwong-joe.medium.com โ€บ passing-a-function-as-a-parameter-in-c-a132e69669f6
Passing a function as a parameter in C++ | Medium - Joe Wong
March 8, 2021 - std::bind(&I_have_a_usefull_function::func, true, std::placeholders::_1)The first parameter "&I_have_a_usefull_function::func" is the function pointer you want to pass.Other parameters are the argument pass to the funciton pointer. In this example, "this" is passed to inside the function body. In this example, the first argument is fixed as true. The second argument and third are set as placeholders 1 and 2 which can be input later. Pro: 1. Valid to pass the local variable in the lambda function.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ c++ โ€บ lambda-expression-in-c
Lambda Expression in C++ - GeeksforGeeks
#include <iostream> using namespace std; int main() { // Defining a lambda auto res = [](int x) { return x + x; }; // Using the lambda cout << res(5); return 0; } ... Explanation: The lambda expression in the above program takes an integer x as input and returns the sum of x with itself. ... Parameters: These parameters are similar to the function parameters in every way.
Published ย  5 days ago
Discussions

c++ - C++11 lambda function - how to pass parameter - Stack Overflow
The type of a lambda function (the so-called "lambda closure") is defined by the compiler, and is a functor with a call operator whose signature is the one you specify when defining the lambda. Therefore, you call a lambda exactly as you would call a functor (i.e. More on stackoverflow.com
๐ŸŒ stackoverflow.com
How do I pass a lambda to a method as a parameter?
Try Func. The last generic type parameter in Func is the return type, so you need three of them: two for the parameters and one for the return type. More on reddit.com
๐ŸŒ r/csharp
27
31
March 6, 2021
When to use a lambda over a function pointer?
So there are three main things I use lambdas for (NOTE: The Reddit numbered list functionality is literally so shitty that I cannot put any code blocks between numbered entries whatsoever, so you get no numbers): They make it easier to pass a function as an argument. Consider the situation where you have a very simple thing to do, but creating an entire separate function is both harder to maintain as well as more difficult to mentally parse. For example: int example(std::vector nums) { return std::accumulate(nums.begin(), nums.end(), 0, [](int acc, int num){ return num > 0 ? acc + num : acc; }); } They allow you to easily bind arguments for functions without needing to use the unnecessarily complicated std::bind. Before lambdas, C++ tried to get first class function using std::function and std::bind. The std::function thing mostly remains, but std::bind has been wholesale replaced by lambdas. struct MyObject { int doSomething(int argument); }; int deriveInfo(std::function f); int example() { MyObject o; // Instead of doing this: // return deriveInfo(std::bind(&MyObject::doSomething, &o)); // You do this: return deriveInfo([&o](int arg){ return o.doSomething(arg); }); } They allow you to create function objects without needing to do all of the class or struct definitions manually. A lambda is effectively an object that runs the function provided upon a call to operator(). As such, if you need to have multiple different function objects passed to the same object or template, this makes it very easy to do so. constexpr static auto A = [](int a, int b){ return example(a * b); }; constexpr static auto B = [](int a, int b){ return example(a + b); }; constexpr static auto C = [](int a, int b){ return example(a - b); }; template constexpr static inline void doSomething(Func f) { f(10, 5); } void someFunc() { doSomething(A); doSomething(B); doSomething(C); } I find lambdas to be quite useful and would be very disappointed if I was forced to make it work with just function pointers. More on reddit.com
๐ŸŒ r/cpp_questions
27
19
September 10, 2023
Use a lambda as a parameter for a C++ function - Stack Overflow
I would like to use a lambda as a parameter for a C++ function, but I don't know which type to specify in the function declaration. What I would like to do is this: void myFunction(WhatToPutHere l... More on stackoverflow.com
๐ŸŒ stackoverflow.com
๐ŸŒ
Microsoft Learn
learn.microsoft.com โ€บ en-us โ€บ dotnet โ€บ csharp โ€บ language-reference โ€บ operators โ€บ lambda-expressions
Lambda expressions - Lambda expressions and anonymous functions - C# reference | Microsoft Learn
January 24, 2026 - For backwards compatibility, if only a single input parameter is named _, the compiler treats _ as the name of that parameter within that lambda expression. Starting with C# 12, you can provide default values for explicitly typed parameter lists. The syntax and the restrictions on default parameter values are the same as for methods and local 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
๐ŸŒ
Quora
quora.com โ€บ Can-lambda-functions-be-used-as-parameters-of-other-functions-in-C-If-so-how-can-this-be-done
Can lambda functions be used as parameters of other functions in C++? If so, how can this be done? - Quora
To pass them to function you must so rely on type deduction and eventually apply type cancellation. To have type deduction, the function taking the lambda must be a template, or having an โ€œautoโ€ type parameter (essentially a shortcut for temp...
Top answer
1 of 3
35

Show lambda with parameters are used? How to pass parameters to them?

It works exactly like with any other type of callable object:

#include <iostream>

int main()
{
    auto l = [] (int i) { std::cout << "The answer is " << i; };
    l(42);
}

Also notice, that you do not need to store a lambda in a variable in order to invoke it. The following is an alternative way to rewrite the above program:

#include <iostream>

int main()
{
    [] (int i) { std::cout << "The answer is " << i; } (42);
    //                                                 ^^^^
    //                                 Invoked immediately!
}

The type of a lambda function (the so-called "lambda closure") is defined by the compiler, and is a functor with a call operator whose signature is the one you specify when defining the lambda. Therefore, you call a lambda exactly as you would call a functor (i.e. exactly as you would call a function - or any callable object).

Thus, if you want to assign a lambda to an object, the best practice is to let the compiler deduce its type by using auto. If you do not want or cannot use auto, then you may:

  1. Use function pointers for non-capturing lambdas (capturing lambdas are not convertible to function pointers). In the above case, thus, the following will also work:

    #include <iostream>
    
    int main()
    {
        void (*f)(int) = [] (int i) { std::cout << "The answer is " << i; };
        f(42);
    }
    
  2. Use std::function (this is always possible, even if the lambda is capturing):

    #include <iostream>
    #include <functional>
    
    int main()
    {
        std::function<void(int)> f = [] (int i) 
                                   { std::cout << "The answer is " << i; };
        f(42);
    }
    
2 of 3
5
auto lambda = [] (int a, int b) { return a + b; };
assert(lambda(1, 2) == 3);
๐ŸŒ
Built In
builtin.com โ€บ software-engineering-perspectives โ€บ c-plus-plus-lambda
C++ Lambda Expressions Explained | Built In
A lambda in C++ is an expression used to simplify code when defining anonymous function objects (functors). Lambdas allow for functors to be defined directly where they are invoked or be passed as function arguments.
Find elsewhere
๐ŸŒ
Johannesugb
johannesugb.github.io โ€บ cpu-programming โ€บ how-to-pass-lambda-functions-in-C++
How To Pass Lambda Functions in C++ (By Value, By L-Value Reference, By Universal Reference) - Johannes Unterguggenberger
January 9, 2021 - This indicates that especially the latter variant โ€“ the one accepting a universal reference โ€“ is the most versatile one since it is the only variant which accepts all different kinds of parameters: mutable lambdas, move-only lambdas, and โ€“ of course โ€“ ordinary lambdas. As reasoned in the answers and comments of the StackOverflow question mentioned initially, the by value variant is probably the one that you should default to.
๐ŸŒ
Reddit
reddit.com โ€บ r/csharp โ€บ how do i pass a lambda to a method as a parameter?
r/csharp on Reddit: How do I pass a lambda to a method as a parameter?
March 6, 2021 -

I've looked over the top dozen or so google posts related to this and similarly worded queries, but I'm still not fully understanding what I'm doing or if it's even possible the way I want to do it.

This is basically what I'm trying to do:

//some function that takes in a lambda and executes it
public static void testFunc(Func<int, int> x){
    Console.WriteLine(x(3, 4));
}

//the call to the function, where a lambda is passed in for x
testFunc((x, y) => (x + y));

Obviously this is way wrong! And I'm the first to admit I don't fully (or even close to) understand lambdas. But this is a result of my desire to be able to avoid explicit delegates for a bunch of functions that are simple arithmetic operations (for the sake of evaluating a postfix string)

Thanks for any help!

๐ŸŒ
Reddit
reddit.com โ€บ r/cpp_questions โ€บ when to use a lambda over a function pointer?
r/cpp_questions on Reddit: When to use a lambda over a function pointer?
September 10, 2023 -

Question seems simple enough.
I've never really understood then point of lambdas. To me the code seems messy, why not use a function pointer instead?

Top answer
1 of 10
25
So there are three main things I use lambdas for (NOTE: The Reddit numbered list functionality is literally so shitty that I cannot put any code blocks between numbered entries whatsoever, so you get no numbers): They make it easier to pass a function as an argument. Consider the situation where you have a very simple thing to do, but creating an entire separate function is both harder to maintain as well as more difficult to mentally parse. For example: int example(std::vector nums) { return std::accumulate(nums.begin(), nums.end(), 0, [](int acc, int num){ return num > 0 ? acc + num : acc; }); } They allow you to easily bind arguments for functions without needing to use the unnecessarily complicated std::bind. Before lambdas, C++ tried to get first class function using std::function and std::bind. The std::function thing mostly remains, but std::bind has been wholesale replaced by lambdas. struct MyObject { int doSomething(int argument); }; int deriveInfo(std::function f); int example() { MyObject o; // Instead of doing this: // return deriveInfo(std::bind(&MyObject::doSomething, &o)); // You do this: return deriveInfo([&o](int arg){ return o.doSomething(arg); }); } They allow you to create function objects without needing to do all of the class or struct definitions manually. A lambda is effectively an object that runs the function provided upon a call to operator(). As such, if you need to have multiple different function objects passed to the same object or template, this makes it very easy to do so. constexpr static auto A = [](int a, int b){ return example(a * b); }; constexpr static auto B = [](int a, int b){ return example(a + b); }; constexpr static auto C = [](int a, int b){ return example(a - b); }; template constexpr static inline void doSomething(Func f) { f(10, 5); } void someFunc() { doSomething(A); doSomething(B); doSomething(C); } I find lambdas to be quite useful and would be very disappointed if I was forced to make it work with just function pointers.
2 of 10
13
Keep in mind a lambda is syntactical sugar for a functor, not a function pointer. Function pointers are very bad from a performance perspective since it prevents inlining. Lambdas and functors are equivalent though.
๐ŸŒ
DZone
dzone.com โ€บ articles โ€บ all-about-lambda-functions-in-cfrom-c11-to-c17
All About Lambda Functions in C++ (From C++11 to C++17)
May 8, 2020 - Lambda with a variable parameter pack will be useful in many scenarios like debugging, repeated operation with different data input, etc. Typically, a lambda's function call operator is const-by-value, which means lambda requires the mutable ...
๐ŸŒ
Cppreference
en.cppreference.com โ€บ w โ€บ cpp โ€บ language โ€บ lambda.html
Lambda expressions (since C++11) - cppreference.com
It appears within a default member initializer, and its innermost enclosing scope is the corresponding class scope. For such lambda expression, the reaching scope is defined as the set of enclosing scopes up to and including the innermost enclosing function (and its parameters).
๐ŸŒ
More of Less
moreofless.co.uk โ€บ lamba-cplusplus
C++ Lambda Anonymous Functions - The Simple Guide
December 14, 2022 - the [] part of the anonymous function definition is the capture part, it's where you can specify variables that you want to remain in scope when the function is run but they aren't actual parameters of the function. Lets change the above code by adding c as a captured variable:
๐ŸŒ
Nextptr
nextptr.com โ€บ tutorial โ€บ ta1188594113 โ€บ passing-cplusplus-captureless-lambda-as-function-pointer-to-c-api
Passing C++ captureless lambda as function pointer to C API - nextptr
A captureless lambda is convertible to a function pointer. It can replace a stand-alone or static member function as a function pointer argument to C API.
๐ŸŒ
Quora
quora.com โ€บ C++-How-to-pass-a-lambda-function-as-a-parameter-of-another-function
C++: How to pass a lambda function as a parameter of another function? - Quora
To have type deduction, the function taking the lambda must be a template, or having an โ€œautoโ€ type parameter (essentially a shortcut for template). This will instatiate the function as many time as the different lambdas you can pass to it.
Top answer
1 of 3
10

A function that just wants to invoke a passed lambda or other functor during its own execution can be a function template, deducing the type of the functor:

template <typename F>
void use_it(F&& func) {
    do_something_with(func());
}

Here you want to store the functor to be invoked later, so we'll need a common type that can wrap around various sorts of functors. This is what std::function is for. Assuming a return type of int:

#include <functional>

class MyObject {
// ...
private:
    std::function<int()> mLambda;
};
void MyObject::SetXGetter(std::function<int()> func) {
    mLambda = std::move(func);
}

Your call is missing the initial [captures] which is required for a lambda expression, even if nothing is captured:

myObject.SetXGetter([]{ return MyGlobals.GetX(); });
2 of 3
3

and I understand this is an area that has improved in more recent C++ versions?

Not in general. It has been expanded to some more complex cases, but the simple cases are pretty much identical to C++11.

Simplest way to pass a lambda as a method parameter in C++17

The options remain the same:

  • You can have a template and pass the lambda as-is.
  • Or you can wrap the lambda in a type erasing wrapper such as std::function in which case you can pass it into a non-template function.
  • Or if the lambda is non-capturing, then it can be converted to a function pointer which can also be passed into a non-template.

Which one is simplest can vary on context and personal opinion. Function wrapper works the same in widest number of different cases, to that's a simple choice. Function pointer doesn't involve dynamic allocation and is simplest to understand at a low level. Template doesn't involve any sort of wrapping or conversion, but it is a template.


this->mLambda = Lambda;

Given that you wish to store the callable as a modifiable member, storing it as a lambda is not an option. You're left with function wrapper and function pointer. You can still use a template for the function, but the lambda must be immediately wrapped or converted anyway, so there isn't much to be gained by using a template.

Top answer
1 of 3
64

Basic version, for use in a header file:

template<typename Lambda>
bool Func1(int Arg1, Lambda Arg2){ // or Lambda&&, which is usually better
  if(Arg1 > 0){
    return Arg2(Arg1);
  } else {
    return false; // remember, all control paths must return a value
  }
}

More complex version, if you want to split your interface from your implementation (it has run time costs):

bool Func1(int Arg1, std::function<bool(int)> Arg2){
  if(Arg1 > 0){
    return Arg2(Arg1);
  } else {
    return false; // remember, all control paths must return a value
  }
}

std::function uses type erasure to create a custom-created wrapper around your lambda, and then exposes a non-virtual interface that uses the pImpl pattern to forward it to the custom-created wrapper.1

Or, in less technical terms, std::function<bool(int)> is a class that can wrap nearly anything that you can call like a function, passing one parameter that is compatible with passing an int, and it returns something that is compatible with returning a bool.

A call through a std::function has a run time cost roughly equal to a virtual function call (caused by the above type erasure), and when you create it it has to copy the state of the function object (aka functor) passed in (which can be cheap -- stateless lambdas, or lambdas capturing arguments by reference -- or expensive in some other cases) and store it (typically on the free store or heap, which has a cost), while the pure-template versions can be "inlined" at the point of call (ie, can not only cost less than a function call, the compiler can even optimize over the function call and return boundaries!)

If you want to split interface/implementation without all of the runtime costs of std::function, you can roll your own function_ref (in c++17, because that cuts down on some boilerplate):

template<class Sig>
struct function_ref;

template<class R, class...Args>
struct function_ref<R(Args...)> {
  R operator()(Args...args) const {
    return pf(state, std::forward<Args>(args)...);
  }
  function_ref()=default;
  function_ref(function_ref const&)=default;
  function_ref& operator=(function_ref const&)=default;
  explicit operator bool()const{ return pf!=nullptr; }

  // this overload reduces indirection by 1 step
  // and allows function_ref<Sig> to resolve overloads
  // on an overload set sometimes.
  function_ref( R(*f)(Args...) ):
    pf([](State const& state, Args&&...args)->R{
      return reinterpret_cast<R(*)(Args...)>(state.pfunstate)(std::forward<Args>(args)...);
    })
  {
    state.pfunstate = reinterpret_cast<void(*)()>(f);
  }

  // this grabs anything callable (that isn't this own type)
  // and stores a pointer to it to call later.
  template<class F>
  requires (
    std::is_convertible_v<
      std::invoke_result_t< std::remove_reference_t<F>, Args... >, R
    >
    && !std::is_same_v< std::decay_t<F>, function_ref >
  )
  function_ref( F&& f ):
    pf([](State const& state, Args&&...args)->R{
      return (*(std::remove_reference_t<F>*)state.pstate)(std::forward<Args>(args)...);
    })
  {
    state.pstate = std::addressof(f);
  }
private:
  union State {
    void* pstate = nullptr;
    void(*pfunstate)();
  };
  State state;
  R(*pf)(State const&, Args&&...) = nullptr;
};
// a deduction guide permitting function_ref{foo} to work
// if foo is a non-overloaded function name.
template<class R, class...Args>
function_ref( R(*)(Args...) )->function_ref<R(Args...)>;

Live example.

This removes the need to ever do any allocation from std::function by removing ownership semantics from it and just type-erasing calling.

A fancy version of the first example that also handles some corner cases a tad better: (also must be implemented within a header file, or in the same translation unit as it is used)

template<typename Lambda>
bool Func1(int Arg1, Lambda&& Arg2){
  if(Arg1 > 0){
    return std::forward<Lambda>(Arg2)(Arg1);
  } else {
    return false; // remember, all control paths must return a value
  }
}

which uses a technique known as "perfect forwarding". For some functors, this generates slightly different behavior than #1 (and usually more correct behavior).

Most of the improvement comes form the use of && in the argument list: this means that a reference to the functor is passed in (instead of a copy), saving some costs, and allows both a const or non-const functor to be passed in.

The std::forward<Lambda>(...) change would only cause a change in behavior if someone used a relatively new C++ feature that allows methods (including operator()) to override on the rvalue/lvalue status of the this pointer. In theory, this could be useful, but the number of functors I've seen that actually override based on the rvalue status of this is 0. When I'm writing serious library code (tm) I go to this bother, but rarely otherwise.

There is one more possible thing to consider. Suppose you want to take either a function that returns bool, or a function that returns void, and if the function returns void you want to treat it as if it returned true. As an example, you are taking a function that is being called when iterating over some collection, and you want to optionally support early halting. The function returns false when it wants to stop prematurely, and true or void otherwise.

Or, in a more general case, if you have multiple overrides of a function, one of which takes a function and others take some other type at the same location.

This is possible, which is as far as I'm going to get into here (either with a smart adapter, or via SFINAE techniques). However, you are probably better off just creating two different named functions, because the techniques required are way too heavy weight.


1 Technically std::function could use magic fairy dust to do what it does, as its behavior is described by the standard, and not its implementation. I'm describing a simple implementation that approximates the behavior of the std::function implementation I have interacted with.

2 of 3
25

First solution:

You can make your Func1() function a function template:

template<typename T>
bool Func1(int Arg1, T&& Arg2){
    if(Arg1 > 0){
        return Arg2(Arg1);
    }

    return false; // <== DO NOT FORGET A return STATEMENT IN A VALUE-RETURNING
                  //     FUNCTION, OR YOU WILL GET UNDEFINED BEHAVIOR IF FLOWING
                  //     OFF THE END OF THE FUNCTION WITHOUT RETURNING ANYTHING
}

You could then invoke it as you desire:

int main()
{
    Func1(12, [](int D) -> bool { return D < 0; } );
}

Second solution:

If you do not want to use templates, an alternative (that would bring some run-time overhead) is to use std::function:

#include <functional>

bool Func1(int Arg1, std::function<bool(int)> Arg2){
    if(Arg1 > 0){
        return Arg2(Arg1);
    }

    return false;
}

Once again, this would allow you to call Func1() the way you desire:

int main()
{
    Func1(12, [](int D) -> bool { return D < 0; } );
}
๐ŸŒ
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 - Parameters: Defines inputs for the Lambda, similar to regular function parameters. Return Type: Specifies the type of value the Lambda will return (optional, as the compiler can infer it in many cases).