You can convert Lambdas to function pointers. What are the practical use cases for this? Why do we need this?
Play with it
int main() {
auto test = []() -> int { return 1; };
using func_point = int (*)();
func_point fp = test;
return test();
}
First, you can only convert lambdas with empty closure. Such lambdas are effectively stateless, which makes the conversion possible.
As for the use cases, one important use case is integration with C. There are plenty C APIs, which allow registration of user callbacks, usually taking one or more arguments, like this:
// Registers callback to be called with the specified state pointer
void register_callback(void (*callback)(void* state), void* state);
You can associate the state with a C++ class instance and translate the callback invokation to a method call:
class Foo
{
public:
void method();
};
Foo foo;
register_callback([](void* p) { static_cast< Foo* >(p)->method(); }, &foo);
Alternatives to function pointers are std::function and template parameters / generic functors. All of those impact your code in different ways.
You can pass lambdas to code that expects either std::function, generic functors or function pointers. It is convenient to have a single concept in the calling code that supports all those different interface concepts so consistently and after all, convenience is all, lambdas are about.
Just to make this complete:
function pointers are the least universal concept of the ones above, so not every lambda can be turned into a function pointer. The capture clause must be empty.
Prefixing lambdas with a + explicitly casts them to a function pointer, if possible, i.e. in the following snippet, f has the type int (*)( int ): auto f = +[]( int x ) { return x; };
Related
I am building a c++ class library for embedded projects.
One concept I have is a class named Task.
Task has 2 members:
An integer id and a callback function pointer
The callbacks are created by the user and given to the constructor of the class.
I want to give the following options to the user:
The user may use functions of type void(*)(void)
The user may use function of type void (*)(unsigned int). That parameter should be the id of the task, when the callback is called.
The user may use a combination of the above function types for different tasks
The tasks also have an execute() method that calls the callback function. This method should also provide the task id as an argument, if needed
One solution would be to add a boolean member in Task called 'has_arguments' and overload the constructor to set it with regard to the type of function pointer it was given in the code.
I could also use a union for the callback member or use a void pointer and cast it to whatever suitable during execution.
The execution of the task would involve checking the 'has_arguments' member, casting the pointer to the appropriate type and calling the callback in the right way.
But is there any way to avoid this extra member and check?
I tried to always cast the function pointers to void(*)(unsigned int) and always provide the argument when I called them. And it worked.
So is it that bad to call a functions that takes no arguments, with an argument?
It worked for me, but I suppose that it is a really bad practice.
Any other ideas on what I could implement instead?
I don't want to dictate to the users to make functions with variable arguments lists. I want to leave them the freedom to use simple task agnostic functions,
or make more intelligent functions that are aware of their task ID
So is it that bad to call a functions that takes no arguments with an argument?
Yes of course!
It worked for me, but I suppose that it is a really bad practice
"It worked for me" isn't a very valid argument if your program has undefined behavior. Because it might not work for me.
Any other ideas how I could implement instead?
A tagged union is really the best way to implement this sort of thing in my opinion. You can always use boot::variant or std::variant for a safer tagged union if you can.
Really, having just one extra member (which is a bool) isn't going to destroy your performance, same for the additional branches that you will have to introduce, even on embedded. Measure first, you can then always optimize if you find that the branches are indeed bottlenecks. :)
If you cannot use std::function due to limitation of embedded platform use union and a tag, then properly set type by overloaded setter or ctor and in call use a switch on type:
struct Task {
enum CallbackType {
cbVoid,
cbId
};
using VoidCb = void(*)(void);
using IdCb = void(*)(unsigned);
int id = 0;
CallbackType type;
union {
VoidCb vcb;
IdCb idcb;
} function;
Task( VoidCb cb ) : type( cbVoid ), function( cb ) {}
Task( IdCb cb ) : type( cbId ), function( cb ) {}
void call() {
switch( type ) {
case cbVoid : function.vcb(); return;
case cbId : function.idcb( id ); return;
}
}
};
Calling a function through a function pointer that has been casted to a different type invokes undefined behaviour (cf. thins online C++ standard draft concerning casting of function pointers):
A function pointer can be explicitly converted to a function pointer
of a different type. The effect of calling a function through a
pointer to a function type ([dcl.fct]) that is not the same as the
type used in the definition of the function is undefined. Except that
converting a prvalue of type “pointer to T1” to the type “pointer to
T2” (where T1 and T2 are function types) and back to its original type
yields the original pointer value, the result of such a pointer
conversion is unspecified. [ Note: see also [conv.ptr] for more
details of pointer conversions. — end note ]
Hence, you should not use it / do it as described in your question.
A way to overcome this problem would be to enforce that correct function pointers are stored for the one and for the other case. This could be done through a discriminator / type data member and two separate function pointer members (or a union of these two separate function pointers) as described in the answer of #Slava.
Another approach could be to distinguish different task types and use inheritance and overriding to perform the callbacks correctly. Of course, this influences the way you will create / use your tasks. But maybe it solves your problem in a more extensible way than with type members and unions.
typedef void(*VoidCallbackType)(void) ;
typedef void(*IdCallbackType)(unsigned) ;
struct Task {
virtual void doCallback() = 0;
};
struct TaskWithId : Task {
unsigned id;
IdCallbackType cb;
TaskWithId(unsigned id, IdCallbackType cb) : id(id), cb(cb) { }
virtual void doCallback() {
cb(id);
}
};
struct TaskWithoutId: Task {
VoidCallbackType cb;
TaskWithoutId(VoidCallbackType cb) : cb(cb) { }
virtual void doCallback() {
cb();
}
};
You can create something under the covers that looks like the same interface. That is, auto-create helper wrapper functions that can throw away the task id if the callback doesn't want it.
class Task {
template <void (*CB)(void)> struct task_void {
static void cb (int) { CB(); }
operator Task () const { return Task(*this); }
};
template <void (*CB)(int)> struct task_int {
static void cb (int id) { CB(id); }
operator Task () const { return Task(*this); }
};
static volatile int next_id_;
int id_;
void (*cb_)(int);
template <typename CB> Task (CB) : id_(next_id_++), cb_(CB::cb) {}
public:
template <void (*CB)(void)> static Task make () { return task_void<CB>(); }
template <void (*CB)(int)> static Task make () { return task_int<CB>(); }
void execute () { cb_(id_); }
};
The private constructor is accessible to the helper templates for initialization. The helper templates can choose to hide the parameter or not.
So now, you can create a task with either kind of callback.
void cb_void () {
std::cout << __func__ << std::endl;
}
void cb_int (int id) {
std::cout << __func__ << ':' << id << std::endl;
}
//...
Task t1 = Task::make<cb_void>();
Task t2 = Task::make<cb_int>();
t1.execute();
t2.execute();
Fairly simple question:
I have a class that uses a (variable) heuristic function to perform a certain algorithm. This heuristic function should ideally be fed to the class constructor as some sort of pointer and implement the following declaration:
int heuristic_Function(GridLocation a, GridLocation b);
What is the best way to accomplish this? Ideally I would like to avoid additional classes and keep the code fairly self-contained (and yes, I am aware of things like delegates and the strategy pattern).
(This has probably been asked hundreds of times already but in different terms)
Well, as you said, you could store a function pointer:
struct Algo
{
using HeurFn = int(GridLocation, GridLocation);
Algo(HeurFn * heuristic) : heuristic_(heuristic) {}
void Run()
{
// use "heuristic_(a, b)"
}
HeurFn * heuristic_;
};
Then instantiate it:
extern int my_fn(GridLocation, GridLocation);
Algo algo(my_fn);
algo.Run();
An alternative would be to pass the function directly to Run, in which case you could make Run a template and perhaps allow for inlining of the actual heuristic code, but you explicitly asked for the heuristic to be configured via the constructor.
Instead of old C function pointer, I would recommend std::function.
So you could write it like this
#include <functional>
struct algorithm{
algorithm (std::function<int(GridLocation, GridLocation)> heuristic_function) :
heuristic(heuristic_function) {}
int do_something (GridLocation a, GridLocation b){
return heuristic(a,b);
}
private:
std::function<int(GridLocation, GridLocation)> heuristic;
}
Advantages are the better readable syntax, and that the caller can use std::bind expressions.
Or you could just take the heuristic as a template, but then you would to either make your algorithm to just a function or write the type to every new instance. See https://stackoverflow.com/a/2156899/3537677
Things get really simple if only the method that does the computations needs the function, and you can forgo storing the function in the class itself. You can then parametrize the method on the type of the passed function, and you get full flexibility:
struct Calculate {
template <typename F> int run(F && f) {
return f(1, 2);
}
};
int f1(int, int) { return 0; }
struct F2 {
int operator()(int, int) { return 0; }
};
int main() {
Calculate calc;
// pass a C function pointer
calc.run(f1);
// pass a C++98 functor
calc.run(F2());
// pass a C++11 stateless lambda
calc.run(+[](int a, int b) -> int { return a-b; });
// pass a C++11 stateful lambda
int k = 8;
calc.run([k](int a, int b) -> int { return a*b+k; });
}
You don't need to manually spell out any types, and you can pass function-like objects that can be stateful.
The power of C++11 comes from the && syntax. There's more to it than meets the eye. In run's parameter, F is a deduced type, and && is a universal reference. That means that, depending on the context, it acts either as an lvalue-reference we know from C++98, or as an rvalue-reference.
The + operator applied to the lambda stresses that it is in fact stateless. Its uses forces a conversion from the abstract lambda type to a C function pointer. The type of the +[](int,int)->int {...} expression is int(*)(int,int). The use of the + operator is not necessary, I've only used it to underline the statelessness.
I've been using function pointers till now, like this format in c++. I do have some uses now and then and I'm wondering is there anything else introduced in c++11/14 as their alternative.
#include <iostream>
using namespace std;
void sayHello();
void someFunction(void f());
int main() {
someFunction(sayHello);
return 0;
}
void sayHello(){
std::cout<<"\n Hello World";
}
void someFunction(void f()){
f();
}
I did take a look at this question but couldn't understand any advantages over traditional use of function pointers. Also I would like to ask , is there anything wrong (not recommended) thing with using function pointers since I never see anyone using them. Or any other alternative present.
The question you mention suggest std::function but does not emphasize (or mentions at all) its value when combined with std::bind.
Your example is the simplest possible, but suppose you have a
std::function<void (int, int)> f ;
A function pointer can do more or less the same things. But suppose that you need a function g(int) which is f with second parameter bound to 0. With function pointers you can't do much, with std::function you can do this:
std::function<void(int)> g = std::bind(f, _1, 0) ;
As an alternative to traditional function pointers, C++11 introduced template alias which combined with variadic templates could simplify the function pointer sintax. below, an example of how to create a "template" function pointer:
template <typename R, typename ...ARGS> using function = R(*)(ARGS...);
It can be used this way:
void foo() { ... }
int bar(int) { ... }
double baz(double, float) { ... }
int main()
{
function<void> f1 = foo;
function<int, int> f2 = bar;
function<double, double, float> f3 = baz;
f1(); f2({}); f3({}, {});
return 0;
}
Also, it can deal neatly with function overloads:
void overloaded(int) { std::cout << "int version\n"; }
void overloaded(double) { std::cout << "double version\n"; }
int main()
{
function<void, int> f4 = overloaded;
function<void, double> f5 = overloaded;
f4({}); // int version
f5({}); // double version
return 0;
}
And can be used as a pretty neat way to declare function-pointers parameters:
void callCallback(function<int, int> callback, int value)
{
std::cout << "Calling\n";
std::cout << "v: " << callback(value) << '\n';
std::cout << "Called\n";
}
int main()
{
function<int, int> f2 = bar;
callCallback(f2, {});
return 0;
}
This template alias could be used as an alternative of std::function which doesn't have its drawbacks nor its advantages (good explanation here).
Live demo
As a brief, I think that template alias combined with variadic templates is a good, nice, neat and modern C++ alternative to raw function pointers (this alias still are function pointers after all) but std::function is good, nice, neat and modern C++ as well with good advantages to take into account. To stick in function pointers (or alias) or to choose std::function is up to your implementation needs.
Also I would like to ask , is there anything wrong (not recommended)
thing with using function pointers since I never see anyone using
them.
Yes. Function pointers are terrible, awful things. Firstly, they do not support being generic- so you cannot take a function pointer that, say, takes std::vector<T> for any T. Secondly, they do not support having bound state, so if at any time in the future, anybody, ever, wishes to refer to other state, they are completely screwed. This is especially bad since this includes this for member functions.
There are two approaches to taking functions in C++11. The first is to use a template. The second is to use std::function.
The template kinda looks like this:
template<typename T> void func(F f) {
f();
}
The main advantages here are that it accepts any kind of function object, including function pointer, lambda, functor, bind-result, whatever, and F can have any number of function call overloads with any signature, including templates, and it may have any size with any bound state. So it's super-duper flexible. It's also maximally efficient as the compiler can inline the operator and pass the state directly in the object.
int main() {
int x = 5;
func([=] { std::cout << x; });
}
The main downside here is the usual downsides of templates- it doesn't work for virtual functions and has to be defined in the header.
The other approach is std::function. std::function has many of the same advantages- it can be any size, bind to any state, and be anything callable, but trades a couple off. Mainly, the signature is fixed at type definition time, so you can't have a std::function<void(std::vector<T>)> for some yet-to-be-known T, and there may also be some dynamic indirection/allocation involved (if you can't SBO). The advantage of this is that since std::function is a real concrete type, you can pass it around as with any other object, so it can be used as a virtual function parameter and such things.
Basically, function pointers are just incredibly limited and can't really do anything interesting, and make the API incredibly unflexible. Their abominable syntax is a piss in the ocean and reducing it with a template alias is hilarious but pointless.
I did take a look at this question but couldn't understand any
advantages over traditional use of function pointers. Also I would
like to ask , is there anything wrong (not recommended) thing with
using function pointers since I never see anyone using them.
Normal "global" functions typically don't/can't have state. While it's not necessarily good to have state during traversal in functional programming paradigm, sometimes state might come in handy when it relates orthogonally to what has been changed (heuristics as example). Here functors (or function objects) have the advantage.
Normal functions don't compose very well (creating higher level functions of lower level functions.
Normal functions don't allow for binding additional parameters on the fly.
Sometimes normal functions can act as replacement for lambdas, and visa versa, depending on the context. Often one wouldn't want to write a special function just because you have some very local/specific requirement during "container traversal".
I'm starting to develop applications using C++11 lambdas, and need to convert some types to function pointers. This works perfectly in GCC 4.6.0:
void (* test)() = []()
{
puts("Test!");
};
test();
My problem is when I need to use function or method local variables within the lambda:
const char * text = "test!";
void (* test)() = [&]()
{
puts(text);
};
test();
G++ 4.6.0 gives the cast error code:
main.cpp: In function 'void init(int)':
main.cpp:10:2: error: cannot convert 'main(int argc, char ** argv)::<lambda()>' to 'void (*)()' in initialization
If use auto, it works ok:
const char * text = "Test!";
auto test = [&]()
{
puts(text);
};
test();
My question is: how can I create a type for a lambda with [&]? In my case, I can not use the STL std::function (because my program does not use C++ RTTI and EXCEPTIONS runtime), and It has a simple implementation of function to solve this problem?
I can not use the STL std::function (because my program does not use C++ RTTI and EXCEPTIONS runtime)
Then you may need to write your own equivalent to std::function.
The usual implementation of type erasure for std::function doesn't need RTTI for most of its functionality; it works through regular virtual function calls. So writing your own version is doable.
Indeed, the only things in std::function that need RTTI are the target_type and target functions, which are not the most useful functions in the world. You might be able to just use std::function without calling these functions, assuming that the implementation you're using doesn't need RTTI for its usual business.
Typically, when you disable exception handling, the program simply shuts down and errors out when encountering a throw statement. And since most of the exceptions that a std::function would emit aren't the kind of thing you would be able to recover from (calling an empty function, running out of memory, etc), you can probably just use std::function as is.
Only lambdas with no capture can be converted to a function pointer. This is an extension of lambdas for only this particular case [*]. In general, lambdas are function objects, and you cannot convert a function object to a function.
The alternative for lambdas that have state (capture) is to use std::function rather than a plain function pointer.
[*]: If the lambda that holds state could be converted to function pointer, where would the state be maintained? (Note that there might be multiple instances of this particular lambda, each one with it's own state that needs to be maintained separately)
As has been mentioned, only lambdas that capture nothing can be converted to function pointers.
If you don't want to use or write something like std::function then another alternative is to pass as parameters the things you would otherwise capture. You can even create a struct to hold them.
#include <iostream>
struct captures { int x; };
int (*func)(captures *c) = [](captures *c){ return c->x; };
int main() {
captures c = {10};
std::cout << func(&c) << '\n';
}
Another alternative is to use global/static/thread_local/constexpr variables which do not require capturing.
You can use std::function, it doesn't need any "runtime". Otherwise, look here for a sketch how to implement std::function yourself.
What is the general idea of a delegate in C++? What are they, how are they used and what are they used for?
I'd like to first learn about them in a 'black box' way, but a bit of information on the guts of these things would be great too.
This is not C++ at its purest or cleanest, but I notice that the codebase where I work has them in abundance. I'm hoping to understand them enough, so I can just use them and not have to delve into the horrible nested template awfulness.
These two The Code Project articles explain what I mean but not particularly succinctly:
Member Function Pointers and the Fastest Possible C++ Delegates
The Impossibly Fast C++ Delegates
You have an incredible number of choices to achieve delegates in C++. Here are the ones that came to my mind.
Option 1 : functors:
A function object may be created by implementing operator()
struct Functor
{
// Normal class/struct members
int operator()(double d) // Arbitrary return types and parameter list
{
return (int) d + 1;
}
};
// Use:
Functor f;
int i = f(3.14);
Option 2: lambda expressions (C++11 only)
// Syntax is roughly: [capture](parameter list) -> return type {block}
// Some shortcuts exist
auto func = [](int i) -> double { return 2*i/1.15; };
double d = func(1);
Option 3: function pointers
int f(double d) { ... }
typedef int (*MyFuncT) (double d);
MyFuncT fp = &f;
int a = fp(3.14);
Option 4: pointer to member functions (fastest solution)
See Fast C++ Delegate (on The Code Project).
struct DelegateList
{
int f1(double d) { }
int f2(double d) { }
};
typedef int (DelegateList::* DelegateType)(double d);
DelegateType d = &DelegateList::f1;
DelegateList list;
int a = (list.*d)(3.14);
Option 5: std::function
(or boost::function if your standard library doesn't support it). It is slower, but it is the most flexible.
#include <functional>
std::function<int(double)> f = [can be set to about anything in this answer]
// Usually more useful as a parameter to another functions
Option 6: binding (using std::bind)
Allows setting some parameters in advance, convenient to call a member function for instance.
struct MyClass
{
int DoStuff(double d); // actually a DoStuff(MyClass* this, double d)
};
std::function<int(double d)> f = std::bind(&MyClass::DoStuff, this, std::placeholders::_1);
// auto f = std::bind(...); in C++11
Option 7: templates
Accept anything as long as it matches the argument list.
template <class FunctionT>
int DoSomething(FunctionT func)
{
return func(3.14);
}
A delegate is a class that wraps a pointer or reference to an object instance, a member method of that object's class to be called on that object instance, and provides a method to trigger that call.
Here's an example:
template <class T>
class CCallback
{
public:
typedef void (T::*fn)( int anArg );
CCallback(T& trg, fn op)
: m_rTarget(trg)
, m_Operation(op)
{
}
void Execute( int in )
{
(m_rTarget.*m_Operation)( in );
}
private:
CCallback();
CCallback( const CCallback& );
T& m_rTarget;
fn m_Operation;
};
class A
{
public:
virtual void Fn( int i )
{
}
};
int main( int /*argc*/, char * /*argv*/ )
{
A a;
CCallback<A> cbk( a, &A::Fn );
cbk.Execute( 3 );
}
The need for C++ delegate implementations are a long lasting embarassment to the C++ community.
Every C++ programmer would love to have them, so they eventually use them despite the facts that:
std::function() uses heap operations (and is out of reach for serious embedded programming).
All other implementations make concessions towards either portability or standard conformity to larger or lesser degrees (please verify by inspecting the various delegate implementations here and on codeproject). I have yet to see an implementation which does not use wild reinterpret_casts, Nested class "prototypes" which hopefully produce function pointers of the same size as the one passed in by the user, compiler tricks like first forward declare, then typedef then declare again, this time inheriting from another class or similar shady techniques. While it is a great accomplishment for the implementers who built that, it is still a sad testimoney on how C++ evolves.
Only rarely is it pointed out, that now over 3 C++ standard revisions, delegates were not properly addressed. (Or the lack of language features which allow for straightforward delegate implementations.)
With the way C++11 lambda functions are defined by the standard (each lambda has anonymous, different type), the situation has only improved in some use cases. But for the use case of using delegates in (DLL) library APIs, lambdas alone are still not usable. The common technique here, is to first pack the lambda into a std::function and then pass it across the API.
Very simply, a delegate provides functionality for how a function pointer SHOULD work. There are many limitations of function pointers in C++. A delegate uses some behind-the-scenes template nastyness to create a template-class function-pointer-type-thing that works in the way you might want it to.
ie - you can set them to point at a given function and you can pass them around and call them whenever and wherever you like.
There are some very good examples here:
http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible
http://www.codeproject.com/Articles/11015/The-Impossibly-Fast-C-Delegates
http://www.codeproject.com/Articles/13287/Fast-C-Delegate
An option for delegates in C++ that is not otherwise mentioned here is to do it C style using a function ptr and a context argument. This is probably the same pattern that many asking this question are trying to avoid. But, the pattern is portable, efficient, and is usable in embedded and kernel code.
class SomeClass
{
in someMember;
int SomeFunc( int);
static void EventFunc( void* this__, int a, int b, int c)
{
SomeClass* this_ = static_cast< SomeClass*>( this__);
this_->SomeFunc( a );
this_->someMember = b + c;
}
};
void ScheduleEvent( void (*delegateFunc)( void*, int, int, int), void* delegateContext);
...
SomeClass* someObject = new SomeObject();
...
ScheduleEvent( SomeClass::EventFunc, someObject);
...
Windows Runtime equivalent of a function object in standard C++. One can use the whole function as a parameter (actually that is a function pointer). It is mostly used in conjunction with events. The delegate represents a contract that event handlers much fulfill. It facilitate how a function pointer can work for.