How to Pass and Execute Anonymous Function as Parameter in C++11

How to pass and execute anonymous function as parameter in C++11?

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.

Passing anonymous function as only parameter to another function (C++)

There are multiple ways to do this, but not all will work on all platforms (e.g. because they'd require C++11 features (lambdas).

The more classic approach would be something like this (without an anonymous function):

#include <iostream>

typedef void(*Action)();

void UniqueWrapper(Action action) {
std::cout << "Generic Code 1" << std::endl;
action();
std::cout << "Generic Code 2" << std::endl;
}

void CustomAction(void) {
std::cout << "Custom Code" << std::endl;
}

int main(int argc, char **argv) {
UniqueWrapper(&CustomAction);
return 0;
}

Of course you could use some macro shenanigans to make this more "dynamic".

Once you accept C++11 code as well (which is required to have lambdas as explained), you can do something like this:

#include <iostream>

typedef void(*Action)();

void UniqueWrapper(Action action) {
std::cout << "Generic Code 1" << std::endl;
action();
std::cout << "Generic Code 2" << std::endl;
}

int main(int argc, char **argv) {
UniqueWrapper([](){
std::cout << "Custom Code" << std::endl;
});
return 0;
}

Of course, there's room for more changes, for example you could use std::function rather than a function pointer.

Use a lambda as a parameter for a C++ function

You have 2 ways: make your function template:

template <typename F>
void myFunction(F&& lambda)
{
//some things
}

or erase type (with std::function for example):

void
myFunction(const std::function<void()/*type of your lamdba::operator()*/>& f)
{
//some things
}

How can I pass a class method as a parameter to another function and later call it, preferably making the variable class method signature explicit?

How would I need to change the above code to implement the same thing
using templates instead of std::function + std::bind?

And how about lambdas instead of std::function + std::bind? I
still want to call B:myWay() and B::otherWay() but using lambdas.
I don't want to substitute B:myWay() and B::otherWay() with
lambdas.

You can use a lambda, yes.

Something like [this]() { return myWay(); } that:

  • captures this, and
  • calls a method of the current object.

[Demo]

#include <iostream>  // cout

class A {
protected:
template <typename F>
void complexMethod(F&& f) { f(); }
};

class B : public A {
void myWay() { std::cout << "myWay\n"; }
void otherWay() { std::cout << "otherWay\n"; }
public:
void doingSomething() {
complexMethod([this]() { return myWay(); });
}
void doingAnotherThing() {
complexMethod([this]() { return otherWay(); });
}
};

int main() {
B b{};
b.doingSomething();
b.doingAnotherThing();
}

// Outputs:
//
// myWay
// otherWay

Is there any implementation technique (one of the above or some other)
were I would be able to make variableMethod return type and
parameters explicit? How would I do it?

You could use const std::function<bool(int,double)>& f as the parameter receiving a function for complexMethod. And still pass a lambda. Notice though lambdas are now receiving (int i, double d) (it could be (auto i, auto d) as well).

[Demo]

#include <functional>  // function
#include <ios> // boolalpha
#include <iostream> // cout

class A {
protected:
bool complexMethod(const std::function<bool(int,double)>& f, int i, double d)
{ return f(i, d); }
};

class B : public A {
bool myWay(int a, double b) { return a < static_cast<int>(b); }
bool otherWay(int a, double b) { return a*a < static_cast<int>(b); }
public:
bool doingSomething(int a, double b) {
return complexMethod([this](int i, double d) {
return myWay(i, d); }, a, b);
}
bool doingAnotherThing(int a, double b) {
return complexMethod([this](auto i, auto d) {
return otherWay(i, d); }, a, b);
}
};

int main() {
B b{};
std::cout << std::boolalpha << b.doingSomething(3, 5.5) << "\n";
std::cout << std::boolalpha << b.doingAnotherThing(3, 5.5) << "\n";
}

// Outputs:
//
// true
// false

Notice also the same could be accomplished with templates, although you wouldn't be making the signature explicit.

[Demo]

#include <functional>  // function
#include <ios> // boolalpha
#include <iostream> // cout

class A {
protected:
template <typename F, typename... Args>
auto complexMethod(F&& f, Args&&... args) -> decltype(f(args...))
{ return f(args...); }
};

class B : public A {
bool myWay(int a, double b) { return a < static_cast<int>(b); }
bool otherWay(int a, double b) { return a*a < static_cast<int>(b); }
public:
bool doingSomething(int a, double b) {
return complexMethod([this](auto i, auto d) {
return myWay(i, d); }, a, b);
}
bool doingAnotherThing(int a, double b) {
return complexMethod([this](auto i, auto d) {
return otherWay(i, d); }, a, b);
}
};

int main() {
B b{};
std::cout << std::boolalpha << b.doingSomething(3, 5.5) << "\n";
std::cout << std::boolalpha << b.doingAnotherThing(3, 5.5) << "\n";
}

// Outputs:
//
// true
// false

Which technique is recommended? Why (speed, flexibility,
readility...)?

Item 34 of Scott Meyer's Effective Modern C++ book is titled Prefer lambdas to std::bind. It ends with a summary saying: Lambdas are more readable, more expressive, and may be more efficient than using std::bind. However, it also mentions a case when std::bind may be useful over lambdas.

C++11 lambda function - how to pass parameter

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);
    }

C++ Pass lambda to template parameter

Lambdas in C++14, including their conversion to function pointers, are not constexpr.

In C++17, this is going to change. There are no stable compilers with that feature implemented that I'm aware of (if you find one, can you mention it in the comments below?).

At that point

constexpr auto tmp = []() -> void { std::cout << "Hello world\n"; };
function<+tmp>();

will definitely work. I am uncertain if

function<+[]() -> void { std::cout << "Hello world\n"; }>()

would work; there are some rules about lambdas in unevaluated contexts and inside template argument lists that may be separate from the constexpr lambda problem and may apply here.

We can hack it in C++14.

Create a template class that stores a static copy of a lambda and exposes a static function with the same signature (f_ptr) that calls that static copy of a lambda.

Instantiate it once globally with your lambda.

Pass a pointer to the f_ptr to your template.

So:

template<class L> struct stateless; // todo
template<class L> stateless<L> make_stateless(L l){return std::move(l);}

auto foo = make_stateless( []() -> void { std::cout << "Hello world\n"; } );

function< &foo::f_ptr >();

this is almost certainly not what you want.

C++ using function as parameter

Normally, for readability's sake, you use a typedef to define the custom type like so:

typedef void (* vFunctionCall)(int args);

when defining this typedef you want the returning argument type for the function prototypes you'll be pointing to, to lead the typedef identifier (in this case the void type) and the prototype arguments to follow it (in this case "int args").

When using this typedef as an argument for another function, you would define your function like so (this typedef can be used almost exactly like any other object type):

void funct(int a, vFunctionCall funct2) { ... }

and then used like a normal function, like so:

funct2(a);

So an entire code example would look like this:

typedef void (* vFunctionCall)(int args);

void funct(int a, vFunctionCall funct2)
{
funct2(a);
}

void otherFunct(int a)
{
printf("%i", a);
}

int main()
{
funct(2, (vFunctionCall)otherFunct);
return 0;
}

and would print out:

2

Passing lambda function as parameter C++

First, as mentioned by @tkausl, you should not call the lambdas when you pass them as parameters, because this way the are automatically evaluated and produce values(long doubles in this case), but your function expects a function as a parameter.

Instead you should call the functions you give as parameters in the called function itself(F in this case).

You can use std::function to describe a function prototype, thus avoiding the "ugly" function pointers.

First you need to include the <functional> header file from the standard library.

Then you can write something like this:

template <typename T>
using Func = std::function<T(T)>;

template <typename T>
T F(long double guess, long double tolerance, Func<T> f, Func<T> df);

Where in std::function<long double(long double)> the type in the parentheses denote the type of the function arguments and the type before the parentheses is the return type of the function prototype;



Related Topics



Leave a reply



Submit