Function pointer with specific argument list - c++

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.

Related

C++: What is the use case of Lambda to function pointer conversion?

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

lambda expression to assign a member function pointer

I need the syntax for a lambda expression that will return a pointer to a member function.
For example I have class A:
class A
{
int x;
void (A::*SomeFunction)();
}
I want to set SomeFunction to a lambda. I tried doing it like this:
A a();
a.SomeFunction = [this](){ printf("Hello from lambada %d",this->x);};
The problem is that:
[this](){ printf("Hello from lambda %d",this->x);};
does not give me a pointer to a member function of class A. it gives me a pointer to a normal function. How do i declare inside the lambda that this is a member function of A.
Alternativly if such a thing isn't possible in cpp. How do you suggest I'll access variable x of class A from the function that SomeFunction is pointing at without using virtual functions (this kind of code will run about 700 times per second).
Edit:
To make it clear I do care about performance. but the main reason why I need this is specific design problems not performance.
I understand this is probably not possible to do in cpp.
Workarounds suggestions would be welcomed.
That is not possible for several reasons.
First, a pointer to member function is different in type from a pointer to stand-alone function, and non-capturing lambdas can only be converted to pointers to standalone functions.
Second, your lambda is capturing, and as such, it can not be converted to a pointer to function at all, and can only remain a functor of unspecified type.
However, you shouldn't think too much into it and just store a lambda in a std::function. Granted, you will end with virtual dispatch and some performance degradation associated with that, but 700 times a second is nothing, and you will never detect a hit because of virtual dispatch.
It's impossible to add extra methods to a class after its definition. Therefore, since there are no methods in your class A, it's impossible to ever set A::SomeFunction to point to any non-static method of A. As a workaround, you could have
void (*SomeFunction)(A*);
and
A a {}; // note {} instead of ()
a.SomeFunction = [](A* a){ /* do something with a->x */ };
From the comments:
This is part of an ECS implemention. and I am simply not willing to create a new class for etch system i want to give the user the option to declare the system in the scene constructor or inheriate from the system class.
You want different behavior from the same class without any indirection? You'll have to give up one.
But you don't have to write a class for each system either. You can make the class a template, so the compiler can generate a class for each systems:
template<typename T>
struct A : private T {
A(T function) noexcept : T{std::move(function)} {}
void SomeFunction() {
(*this)(this);
}
int x = 0;
};
It can then be used like that:
auto lambda = [](auto a){ printf("Hello from lambda %d",a->x); };
auto my_a = A{lambda}; // Generate a new A type from lambda
my_a.SomeFunction(); // calls the lambda!
Well following up for future people here's a workaround to make it look a bit nicer.
I created a template class
template <class Parent,class Return, class...Params>
struct MemberLambda
{
Parent* self; // pointer to self
void (*lambda)(Parent * self,Params...);//the lambda
MemberLambda() = default;//Constructor
MemberLambda(Parent* self, void(*lambda)(Parent* self,Params...)) :
self(self),lambda(lambda) {};//Constructor
Return operator()(Params... p) const { return lambda(self,p...); };
void operator=(void (*lambda)(Parent* self, Params...)) {
this->lambda = lambda;
}
};
Usage in class:
class A {
public:
int someMember;
MemberLambda<A, void, int, int> func =
MemberLambda<A, void, int, int>(this, nullptr);
};
*Note in the example I set the lambda to nullptr but it can be set to a lambda expression.
In the example, the lambda is a member of A takes two ints and returns void.
User usage:
A a;
a.someMember = 3;
a.func = [](A* self, int a, int b){ std::cout << self->someMember + a + b; };
a.func(5,6);
Will output 14, which is 3 + 5 + 6.

C/C++: A (*eval(A (*function)(B),B b))(){ ... } possible?? (possibly pre-C++11)

in C/C++ (possibly pre-C++11), is it possible to do
A (*eval(A (*function)(B), B b))(){
// ... ??
}
i.e., a function taking
a function returning an A value from a B value,
a B value to be fed to that function,
which returns
- a function returning an A from ()
...??
If yes, would it be
efficient??
guaranteed the compiler generates code
which is not executed before call of the returned function??
Thanks in advance & cheers, Nick
2014-4-20 (1): Thanks for mentioning the 'evtl.'(fixed) std::bind. :-)
So – to understand – (in C/pre C++11 without Boost) function pointers are exceptional in the way that, inside functions, it is only possible to declare them, but there is no way to produce or modify an instance – as function/method definitions are the only possible sources for function pointer instances, from where these may be handed over either explicitly, or by function/method arguments??
Just asking, as I am not clear about a possible internal representation of function pointers...
2014-4-20 (2): With the contribution of Danvil, it's time for the purpose to reveal, here the same with templates:
template<typename T,typename A>
struct Evaluator {
T(*f)(A);
A a;
T operator()() const { return f(a); }
};
template<typename T,typename A>
Evaluator<T,A> eval(T(*f)(A), A a) {
Evaluator<T,A> w;
w.f= f; w.a= a;
return w;
}
This works, while – as some already might guess – the whole, from arbitrary matching function/arguments collections, is intended to be sent as a zero parameter procedure into a single function/method handling execution similar to a try/catch.
For not having to use mostly identical code for each different parameter count, the actual idea was to generate the still not executed job as a such zero parameter procedure of same type for all cases.
Still, I do not find a way how to construct or modify a function pointer inside a function; 'typecasting' in some way to Evaluator does not seem practicable, does it??
Again, thanks a lot, and Happy Easter... :-)
I think you're looking for std::bind. The name std::bind is new, previously it was part of Boost.
#include <functional>
std::function<A (void)> curry(A (*fn)(B), B b)
{
return std::bind(fn, b);
}
Without C++11 it could work like this:
typedef A(*Func)(B);
struct Evaluator {
Func f;
B b;
A operator()() const
{ return f(b); }
};
Evaluator eval(Func f, B b) {
Evaluator w;
w.f = f;
w.b = b;
return w;
}
That's essentially what std::bind is doing, so use std::bind if you can.

What is a C++ delegate?

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.

Troubles with pointer to methods

I'm just learning C++ and I'm having difficulties regarding pointers to methods. Lets say:
class One {
public:
int Add (int a, int b) {return a+b;}
};
typedef int (One::*pAdd) (int, int);
class Other {
public:
int Next (pAdd funct, int c){ return funct (c, 1);}
};
int main (){
One one;
Other other;
other.Next(one.Add, 2);
return 0;
}
I have a number of problems, as reported by my MinGW. First, I'm not invoking funct correctly, as compiler insists on using .* or ->* . Have no idea how to incorporate this request and any help is welcomed. Now, I could solve my problems by making methods static to use c-style pointers or pass objects and invoke methods from within Next, but I want to understand pointers to methods. Basically, I'm puzzled why one.Add is not an acceptable input. Method to call is unambiguously defined (.Add) and conforms my typedef. Also, I'm providing instance of class (one) from typedef thus providing context in which method is to be executed. But compiler output looks like I didn't only miss the syntax, but like I missed the concept. So, how to pass pointer to method with object as context as a single argument?
The main problem here is that member functions are not associated with an object instance, they are just function pointers with a slightly different signature.
So, when you want to call a member function you need two things: a pointer to the member function and the object instance in which to call it.
I changed your code sample a bit:
#include <iostream>
class One {
public:
int Add (int a, int b) {return a+b;}
};
typedef int (One::*pAdd) (int, int);
class Other {
public:
int Next (One one, pAdd funct, int c){
return (one.*funct)(c, 1);
}
};
int main (){
One one;
Other other;
std::cout << other.Next(one, &One::Add, 2) << std::endl;
return 0;
}
And it works now. It can probably be improved a bit, but I think you can take it from here.
I recommend that you read Pointers to member functions section of the c++ faq lite, which explains this very well.
So, how to pass pointer to method with object as context as a single argument?
Using just member-function pointers, you can't. Although your syntax looks like something that should do that, it just isn't allowed. You need an object to apply the function to:
class Other {
public:
int Next (pAdd funct, One & o, int c){ return (o.*funct) (c, 1);}
}
int main (){
One one;
Other other;
other.Next(&One::Add, one, 2);
}
If you want to create a function object that calls a particular member function of a particular object, then one possibility is to use std::bind (or boost::bind if you can't use C++11 yet):
#include <functional>
class Other {
public:
int Next (std::function<int(int,int)> funct, int c){ return funct (c, 1);}
};
int main (){
One one;
Other other;
using namespace std::placeholders;
other.Next(std::bind(&One::Add, &one, _1, _2), 2);
}
or a lambda:
other.Next([&](int a, int b){return one.Add(a,b);}, 2);
Pointers to members need an instance to operate on. Essentially, they are functions which take an addition parameter which becomes the implicit this pointer. To call a function through a pointer to member for the current object you can use code like this:
(this->*funct)(c, 1);
(you'd access member variables similarly but without a function call).
The object you call the member on isn't part of the pointer to member. As a result you need to get it something like this:
&One::Add
This becomes more interesting if the member function is overloaded: in this case you need to provide a context from which the overload can be determined when taking the address. I tupically use a static_cast<>() for this:
static_cast<int (One::*)(int,int)>(&One::Add)
You have a bunch of problems here: one.Add is a member function and
you cannot just invoke it. You need to have a pointer to the class to
invoke it on as well. Also, you need to use the special operator.*
or operator->*. You can also not take the address of a bound member
function.
All in all, you should use a template and boost/std::bind to make
all this bearable or stay away from it.
Here is modified, working code:
class One {
public:
int Add (int a, int b) {return a+b;}
};
typedef int (One::*pAdd) (int, int);
class Other {
public:
int Next (One* one, pAdd funct, int c){ return (one->*funct)(c, 1);}
};
int main (){
One one;
Other other;
other.Next(&one, &One::Add, 2);
return 0;
}