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{ 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. Answer from WorldWorstProgrammer on reddit.com
🌐
Shaharmike
shaharmike.com › cpp › lambdas-and-functions
Under the hood of lambdas and std::function | Shahar Mike's Web Spot
February 23, 2016 - std::function is a templated object that is used to store and call any callable type, such as functions, objects, lambdas and the result of std::bind.
🌐
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.
Discussions

lambda to std::function template - C++ Forum
Do you realize that a lambda is a callable target? http://en.cppreference.com/w/cpp/utility/functional/function There is an example where a lambda is stored in a std::function, thereby wrapping the lambda. Is that what you are after? More on cplusplus.com
🌐 cplusplus.com
October 27, 2017
Can standard::function be used to pass lambda with captures as function pointer ? If not, is there any way to do this?
You can't pass a std::function to a function that expects a function pointer, what ever it holds. If you have a C api that takes a function pointer, and you have a lambda with a capture, then you're stuck. More on reddit.com
🌐 r/cpp_questions
22
2
December 23, 2022
How does a lambda actually get assigned to a std::function<>?
Hello Group! I'm looking for some insight into how an assignment such as: std::function f = [z](int x, int y){ return x + y + z; }; actually works under the hood. I've been playing around with lambda using a mingw-w64 version of g++: "g++ (GCC) 4.7.0 20110829 (experimental)". According to... More on thecodingforums.com
🌐 thecodingforums.com
9
January 16, 2012
c++ - Lambdas and std::function - Stack Overflow
I'm trying to catch up on C++11 and all the great new features. I'm a bit stuck on lambdas. Here's the code I was able to get to work: #include #include #include... More on stackoverflow.com
🌐 stackoverflow.com
Top answer
1 of 2
80

It's because a lambda function is not a std::function<...>. The type of

auto lambda = [](const std::string& s) { return std::stoi(s); };

is not std::function<int(const std::string&)>, but something unspecified which can be assigned to a std::function. Now, when you call your method, the compiler complains that the types don't match, as conversion would mean to create a temporary which cannot bind to a non-const reference.

This is also not specific to lambda functions as the error happens when you pass a normal function. This won't work either:

int f(std::string const&) {return 0;}

int main()
{
    std::vector<int> vec;
    C<int> c;
    c.func(vec, f);
}

You can either assign the lambda to a std::function

std::function<int(const std::string&)> lambda = [](const std::string& s) { return std::stoi(s); };

,change your member-function to take the function by value or const-reference or make the function parameter a template type. This will be slightly more efficient in case you pass a lambda or normal function pointer, but I personally like the expressive std::function type in the signature.

template<typename T>
class C{
    public:
    void func(std::vector<T>& vec, std::function<T( const std::string)> f){
        //Do Something
    }

    // or
    void func(std::vector<T>& vec, std::function<T( const std::string)> const& f){
        //Do Something
    }

    // or
    template<typename F> func(std::vector<T>& vec, F f){
        //Do Something
    }
};
2 of 2
36

It's because the argument (std::function) is a reference. It should be:

void func(std::vector<T>& vec, std::function<T(const std::string&)> f)
                                                                ^  ^
                                                                   |
                                                                   f not a reference

So that the argument can be converted to the parameter type.

Also, the type of the function should match. I.e. it should accept a string reference.

🌐
GitHub
gist.github.com › cd626ea3685fd5e8bf14
Convert lambda to std::function · GitHub
Convert lambda to std::function. GitHub Gist: instantly share code, notes, and snippets.
🌐
Cppreference
en.cppreference.com › w › cpp › utility › functional › function.html
std::function - cppreference.com
#include <functional> #include <iostream> struct Foo { Foo(int num) : num_(num) {} void print_add(int i) const { std::cout << num_ + i << '\n'; } int num_; }; void print_num(int i) { std::cout << i << '\n'; } struct PrintNum { void operator()(int i) const { std::cout << i << '\n'; } }; int main() { // store a free function std::function<void(int)> f_display = print_num; f_display(-9); // store a lambda std::function<void()> f_display_42 = []() { print_num(42); }; f_display_42(); // store the result of a call to std::bind std::function<void()> f_display_31337 = std::bind(print_num, 31337); f_di
🌐
W3Schools
w3schools.com › cpp › cpp_functions_lambda.asp
C++ Lambda Functions
You can pass values into a lambda just like a regular function: #include <iostream> using namespace std; int main() { auto add = [](int a, int b) { return a + b; }; cout << add(3, 4); return 0; } Result: 7 Try it Yourself » · You can also pass a lambda function as an argument to another function.
🌐
Cppreference
en.cppreference.com › w › cpp › language › lambda.html
Lambda expressions (since C++11) - cppreference.com
The lambda expression is a prvalue expression of unique unnamed non-union non-aggregate class type, known as closure type, which is declared (for the purposes of ADL) in the smallest block scope, class scope, or namespace scope that contains the lambda expression.
Find elsewhere
🌐
Lesleylai
lesleylai.info › en › std-function
What is std::function in C++, and why do we need them? | Lesley Lai
January 18, 2021 - To make func accepts both lambda and lambda2, std::function needs to have constructors that take any function object or plain function that satisfies its signature.
🌐
Cplusplus
cplusplus.com › forum › general › 223816
lambda to std::function template - C++ Forum
October 27, 2017 - Do you realize that a lambda is a callable target? http://en.cppreference.com/w/cpp/utility/functional/function There is an example where a lambda is stored in a std::function, thereby wrapping the lambda. Is that what you are after?
🌐
Alandefreitas
alandefreitas.github.io › moderncpp › basic-syntax › functions › lambda
Lambda Functions - Modern C++
Lambdas in function calls · Store lambda as std::function · Capturing values in lambda function · Parameter type deduction · Binding parameters to the function · Bind a single parameter · Keep parameters and convert the return type · Sorting with lambdas ·
🌐
Medium
medium.com › @briankworld › introduction-to-c-lambdas-and-using-them-with-standard-library-algorithms-bef29ef80dd8
Introduction to C++ Lambdas and Using Them with Standard Library Algorithms | by Brian | Medium
May 6, 2023 - It allows you to define a function on the fly and pass it as a parameter to another function or use it directly. ... Lambda expressions are often used in C++ with STL algorithms like std::for_each, std::transform, and std::sort to provide custom ...
🌐
MC++ BLOG
modernescpp.com › index.php › c-core-guidelines-function-objects-and-lambas
C++ Core Guidelines: Function Objects and Lambdas – MC++ BLOG
September 29, 2017 - With C++14, we have generic lambdas; therefore, you can define a lambda expression such as [](auto a, auto b){ return a + b; };. What does that mean for the call operator of AddObj? I assume you can already guess it. The call operator becomes a template. I want to emphasize it explicitly: a generic lambda is a function template.
🌐
The Coding Forums
thecodingforums.com › archive › archive › c++
How does a lambda actually get assigned to a std::function<>? | C++ | Coding Forums
January 16, 2012 - Does std::function wrap a copy of or a reference to the actual instance of the lambda? Presumably std::function doesn't know anything about capture lists, so it would need the lambda to manage that. One last question: If I try to assign, say, a double to a std::function, I get a compiler error "cannot be used as a function".
🌐
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 - Figure 1: Two versions of a function, the left accepts a lambda by value, the right accepts it by const reference. Figure 2: The assembly code of the two versions from Figure 1 compared with each other. Where it can make a difference is when the lambda captures data. If a lambda captures large amounts of data, that data would have to be copied whenever a lambda is passed by value. Let us assume that a lambda captures a large vector by value, as shown in Code Listing 2. std::vector<uint8_t> blob; auto lambda = [blob](){ };
🌐
DEV Community
dev.to › pratikparvati › lambda-functions-in-c-39dh
Lambda Functions in C++ - DEV Community
June 13, 2021 - There are three possible ways to give lambda a name. we can use std::function<> to hold the function pointer.
🌐
a place to jot
wirepair.org › 2023 › 11 › 15 › stdfunction-lambda-and-testing
std::function, Lambda and Testing – a place to jot
November 15, 2023 - It inherits from SocketSender and implements the override’s necessary for Send/SendTo. But it also has a single public member std::function<size_t(const void *Buffer, const int Len)> SendFn = nullptr;. This std::function is what I can override in my tests.
🌐
Learn C++
learncpp.com › cpp-tutorial › introduction-to-lambdas-anonymous-functions
20.6 — Introduction to lambdas (anonymous functions) – Learn C++
January 3, 2020 - Although we don’t know the type of a lambda, there are several ways of storing a lambda for use post-definition. If the lambda has an empty capture clause (nothing between the hard brackets []), we can use a regular function pointer. std::function or type deduction via the auto keyword will also work (even if the lambda has a non-empty capture clause).
Top answer
1 of 2
11

Stephan T. Lavavej explains why this doesn't work in this video. Basically, the problem is that the compiler tries to deduce BaseT from both the std::vector and the std::function parameter. A lambda in C++ is not of type std::function, it's an unnamed, unique non-union type that is convertible to a function pointer if it doesn't have a capture list (empty []). On the other hand, a std::function object can be created from any possible type of callable entity (function pointers, member function pointers, function objects).

Note that I personally don't understand why you would want to limit the incoming functors to that specific signature (in addition to the fact that indirection through a polymorphic function wrapper, like std::function, is by far more inefficient than a direct call to a functor (which may even be inlined)), but here's a working version. Basically, it disables argument deduction on the std::function part, and only deduces BaseT from the std::vector argument:

template<class T>
struct Identity{
  typedef T type;
};

template<typename BaseT>
vector<BaseT> findMatches(vector<BaseT> search, 
    typename Identity<function<bool (const BaseT &)>>::type func)
{
    vector<BaseT> tmp;

    for(auto item : search)
    {
        if( func(item) )
        {
            tmp.push_back(item);
        }
    }

    return tmp;
}

Live example on Ideone.

Another possible way would be to not restrict the functor type directly, but indirectly through SFINAE:

template<class T, class F>
auto f(std::vector<T> v, F fun)
    -> decltype(bool(fun(v[0])), void())
{
  // ...
}

Live example on Ideone.

This function will be removed from the overload set if fun doesn't take an argument of type T& or if the return type is not convertible to bool. The , void() makes f's return type void.

2 of 2
0

As has been revealed by other posters, this is a template argument deduction for std::function.

One intuitive way to make the second code snippet work is to add your base type when calling the template function: findMatches<int>.

Another way not mentioned by Xeo is using std::is_convertible:

template<typename BaseT, typename FUNC>
vector<BaseT> findMatches(vector<BaseT> search, function <bool (const BaseT &)> func)
{
    static_assert(std::is_convertible<FUNC, function<bool (const BaseT &)> >::value, "func must be convertible to ...");

    vector<BaseT> tmp;

    for(auto item : search)
    {
        if( func(item) )
        {
            tmp.push_back(item);
        }
    }

    return tmp;
}

It avoids wrapping lamda into std::function, and provides a cleaner error message.