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
    }
};
Answer from Jens on Stack Overflow
🌐
Shaharmike
shaharmike.com › cpp › lambdas-and-functions
Under the hood of lambdas and std::function | Shahar Mike's Web Spot
February 23, 2016 - $ clang++ main.cpp -std=c++14 && ./a.out Assigning lambda1 of size 16 Assigning lambda2 of size 17 Allocating 17 bytes · 17. That’s the threshold beyond which std::function reverts to dynamic allocation (on clang).
🌐
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
Discussions

c++ - I cannot pass lambda as std::function - Stack Overflow
Please explain me what is not ok and how to implement it with std::bind as well. ... It's because a lambda function is not a std::function<...>. The type of More on stackoverflow.com
🌐 stackoverflow.com
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
c++ - How to convert a lambda to an std::function using templates - Stack Overflow
My goal was to be able to do something ... to use std::bind and have used it extensively before. This problem on the other hand is simply a challenge to see what I can accomplish with variadic templates. 2012-11-13T10:30:24.8Z+00:00 ... @retep998: in your example code, your lambda captures nothing and therefore is convertible to a function ... More on stackoverflow.com
🌐 stackoverflow.com
lambda to std::function template - C++ Forum
I want a template function('Convert') ... Convert([](int&){});//f3 type is std::function; how to implement 'Convert'? ... 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 ... More on cplusplus.com
🌐 cplusplus.com
October 27, 2017
🌐
W3Schools
w3schools.com › cpp › cpp_functions_lambda.asp
C++ Lambda Functions
Note that you must include the <functional> library for this example to work. You can define and use a lambda function inside a loop, which are great for quick actions: #include <iostream> using namespace std; int main() { for (int i = 1; i <= 3; i++) { auto show = [i]() { cout << "Number: " << i << "\n"; }; show(); } return 0; } Result: Number: 1 Number: 2 Number: 3 Try it Yourself » ·
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.

🌐
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.
🌐
Cppreference
en.cppreference.com › w › cpp › language › lambda.html
Lambda expressions (since C++11) - cppreference.com
This example shows how to pass a lambda to a generic algorithm and how objects resulting from a lambda expression can be stored in std::function objects.
🌐
Rip Tutorial
riptutorial.com › std::function with lambda and std::bind
C++ Tutorial => std::function with lambda and std::bind
#include <iostream> #include ... example int stdf_foobar (int x, std::function<int(int)> moo) { return x + moo(x); // std::function moo called } int foo (int x) { return 2+x; } int foo_2 (int x, int y) { return 9*x + y; } int main() { int a = 2; /* ...
Find elsewhere
🌐
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 - Introduction to C++ Lambdas and Using Them with Standard Library Algorithms A lambda expression in C++ is a shorthand syntax for defining an anonymous function object that can be used in place of a …
🌐
Microsoft Learn
learn.microsoft.com › en-us › cpp › cpp › lambda-expressions-in-cpp
Lambda expressions in C++ | Microsoft Learn
In C++14, you can introduce and ... in the lambda function's enclosing scope. The initialization can be expressed as any arbitrary expression; the type of the new variable is deduced from the type produced by the expression. This feature lets you capture move-only variables (such as std::unique_ptr) ...
🌐
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 - Here is an example of undefined behavior with lambda expressions. // lambdaCaptureReference.cpp #include <functional> #include <iostream> std::function<int(int)> makeLambda(int a){ int local = 2 * a; auto lam = [&local](int b){ return local + b; }; // 1 std::cout << "lam(5): "<< lam(5) << std::endl; // 2 return lam; } int main(){ std::cout << std::endl; int local = 10; auto addLocal = [&local](int b){ return local + b; }; // 3 auto add10 = makeLambda(5); std::cout << "addLocal(5): " << addLocal(5) << std::endl; // 4 std::cout << "add10(5): " << add10(5) << std::endl; // 5 std::cout << std::endl; }
🌐
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 ·
🌐
GitHub
gist.github.com › cd626ea3685fd5e8bf14
Convert lambda to std::function · GitHub
Convert lambda to std::function · Raw · lambda_to_function.cpp · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Top answer
1 of 10
55

You can't pass a lambda function object as an argument of type std::function<T> without explicitly specifying the template argument T. Template type deduction tries to match the type of your lambda function to the std::function<T> which it just can't do in this case - these types are not the same. Template type deduction doesn't consider conversions between types.

It is possible if you can give it some other way to deduce the type. You can do this by wrapping the function argument in an identity type so that it doesn't fail on trying to match the lambda to std::function (because dependent types are just ignored by type deduction) and giving some other arguments.

template <typename T>
struct identity
{
  typedef T type;
};

template <typename... T>
void func(typename identity<std::function<void(T...)>>::type f, T... values) {
  f(values...);
}

int main() {
  func([](int x, int y, int z) { std::cout << (x*y*z) << std::endl; }, 3, 6, 8);
  return 0;
}

This is obviously not useful in your situation though because you don't want to pass the values until later.

Since you don't want to specify the template parameters, nor do you want to pass other arguments from which the template parameters can be deduced, the compiler won't be able to deduce the type of your std::function argument.

2 of 10
31

TL;DR: What you ask can be done using CTAD, a feature that enables you to create an std::function of the expected type, right at the call site without spelling out the template arguments:

foo(std::function([](int arg){ return Bar{}; }));
//  ^^^^^^^^^^^^^ constructor call w/o templates
// std::function<Bar(int)>  will be auto-deduced

Demo

If you are interested on how to emulate the mechanics of such a deduction, or need to work with a pre c++17 compiler, check the rest of the answer.


You can use a dedicated/retrospective cast. Once you have a tool like this

#include <functional>

using namespace std;

template<typename T>
struct memfun_type
{
    using type = void;
};

template<typename Ret, typename Class, typename... Args>
struct memfun_type<Ret(Class::*)(Args...) const>
{
    using type = std::function<Ret(Args...)>;
};

template<typename F>
typename memfun_type<decltype(&F::operator())>::type
FFL(F const &func)
{ // Function from lambda !
    return func;
}

you can say FFL() to all lambda types to have them converted to what would be the correct version of std::function

template <typename... Args> void Callback(std::function<void(Args...)> f){
    // store f and call later
}

int main()
{
    Callback(FFL([](int a, float b){
        // do something
    }));

    return 0;
}

Display

🌐
Laefy
laefy.github.io › CPP_Learning › chapter6 › 4-lambdas
Lambdas :: Cours de C++ - Niveau Master
Les lambdas peuvent être placées dans des variables locales ayant pour type auto : const auto compare_stuff = [](const Stuff& stuff1, const Stuff& stuff2) { return stuff1.content == stuff2.content; }; Stuff stuff1 { 1 }, stuff2 { 2 }, stuff3 { 2 }, stuff4 { 1 }; if (compare_stuff(stuff1, stuff2) && compare_stuff(stuff2, stuff3)) { assert(compare_stuff(stuff1, stuff3)); } On peut également les assigner à des objets de type std::function<Ret(Params...)> si la signature de la lambda correspond bien au paramètre de template de la std::function :
🌐
Cplusplus
cplusplus.com › forum › general › 223816
lambda to std::function template - C++ Forum
October 27, 2017 - I want a template function('Convert') ... 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....
🌐
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
🌐
Lesleylai
lesleylai.info › en › std-function
What is std::function in C++, and why do we need them? | Lesley Lai
January 18, 2021 - For example: ... A canonical use case for storing an invocable in this fashion is a task system, where you probably want to store callbacks in a container to execute later: ... 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.
🌐
GeeksforGeeks
geeksforgeeks.org › c++ › lambda-expression-in-c
Lambda Expression in C++ - GeeksforGeeks
A lambda expression can have more power than an ordinary function by having access to variables from the enclosing scope. We can capture external variables from the enclosing scope in three ways using capture clause: ... Note: A lambda with an empty capture clause [] can only access variables which are local to it. ... #include <iostream> #include <vector> using namespace std; void print(const vector<int>& v) { for (auto x : v) cout << x << " "; cout << endl; } int main() { vector<int> v1, v2; // Capture all by reference auto byRef = [&](int m) { v1.push_back(m); v2.push_back(m); }; // Capture
Published   5 days ago
🌐
USACO Guide
usaco.guide › home › general › (optional) c++ - lambda expressions
(Optional) C++ - Lambda Expressions · USACO Guide
You can also specify what variables to capture, but this typically is not necessary. For an example of a lambda, say we want to write a function returns the square of a given number.
🌐
University of Chicago
naipc.uchicago.edu › 2014 › ref › cppreference › en › cpp › language › lambda.html
Lambda functions (since C++11) - cppreference.com
This example shows (a) how to pass a lambda to a generic algorithm and (b) how objects resulting from a lambda declaration can be stored in std::function objects.