Can you please explain what does the following line means?
typedef int (*Callback)(void * const param,int s)
It means that Callback is a new name for the type : pointer to a function returning an int and taking two parameters of type 'const pointer to void' and 'int'.
Given a function f :
int f(void * const param, int s)
{
/* ... */
}
The Callback can be used to store a pointer to f :
Callback c = &f;
The function f can be later invoked through the pointer without directly referring to its name :
int result = c(NULL, 0);
At the point of the call, the name f does not appear.
It creates a new "alias" or name by which you can refer to pointers to functions that return int and take two parameters: a void* const and an int. You can then create variables of that type, assign to them, invoke the function through them etc as in:
int fn(void * const param,int s) { ... }
Callback p;
p = fn;
int x = p(NULL, 38);
Note that typedefs do not really create new types... every equivalent typedef is resolved to the single real type for the purposes of overload resolution, template instantiation etc..
It declares a function type:
// Set up Callback as a type that represents a function pointer
typedef int (*Callback)(void * const param,int s);
// A function that matches the Callback type
int myFunction(void* const param,int s)
{
// STUFF
return 1;
}
int main()
{
// declare a variable and assign to it.
Callback funcPtr = &myFunction;
}
Related
void Frame::ExtractORB(int flag, const cv::Mat &im)
{
if(flag==0)
(*mpORBextractorLeft)(im,cv::Mat(),mvKeys,mDescriptors);
else
(*mpORBextractorRight)(im,cv::Mat(),mvKeysRight,mDescriptorsRight);
}
How to use like this format?
(*name)(param1, param2, param3, param4)
this code is belong to orb_slam ....
https://github.com/raulmur/ORB_SLAM2
A declaration of a pointer to a non-member function has the following structure:
return-type (* name)(argument-list)
So in order to declare a pointer functo a function taking a const char* and an intas an argument and returning bool you say
bool (*func)(const char*, int);
Note, that you need the parenthesis around the *func, because otherwise the compiler would interpret it as a declaration of function
bool* func(const char*, int);
returning bool*.
Assume now, that you have a function
bool foo(const char* x, int y) { /* ... */ }
of corresponding type, then you can make your pointer point to this function by
func = &foo;
In order to invoke the function pointed to by func, you dereference the pointer and invoke it with the arguments like this
bool result = (*func)("abc", 3);
This is what you are doing in the example you provided. Calling the function pointed to by mpORBextractorLeft (resp. mpORBextractorRight) with the given arguments.
Some further notes:
Dereferencing of the function pointer may be omitted, so
bool result = func("abc", 3);
should work as well.
When declaring the pointer, it can be initialized immediately:
bool (*func)(const char*, int) = &foo;
A typedef can be used to simplify code if you need to write the type of the pointer multiple times:
typedef bool (*fun_ptr)(const char*, int);
fun_ptr func1 = &foo;
fun_ptr func2 = &bar;
I would like to do the following. Say I have this:
void f(const char* c) {
// Do stuff with c
}
void g(const char* c, int x, int y) {
// Do other stuff
}
What I'd like to do is to create a function from g that takes a const char* c. That is:
int a = 5;
int b = 9;
expression(g, a, b)("Hi!");
Preferably, expression(g) can be stored in a variable as well. I'm not sure how to declare this variable either.
I have tried using boost::bind; however boost::bind returns a boost::function, and I would like a normal C++ function pointer. Additionally, I also saw this thread:
demote boost::function to a plain function pointer
And neither of the top two solution will work. My function f is constrained to take one parameter (no void* user_data pointer). The reason I need this is that I have a third function, h, that takes in a function of one argument, namely a const char* and does things with it. I'd like to be able to pass in a form of g to h.
h(f) // Valid
h(expression(g, a, b)) // Would like for this to be valid, too
I'm not sure if this is possible, but if it is, do tell :).
Use bind:
#include <functional>
auto h = std::bind(g, std::placeholders::_1, 5, 9);
h("hi");
bind makes copies of the arguments, so beware if you're planning on taking arguments by reference (in which case you may want std::ref). Try to keep the result type auto to avoid unnecessary conversions.
To get a normal C++ function:
void h(char const * s) { g(s, 5, 9); }
Or:
void (*ph)(char const *) = [](const char * s) { g(s, 5, 9); };
Or for the insane:
struct Foo { static void bar(char const * s) { g(s, 5, 9); } };
void (*qh)(char const *) = &Foo::bar;
Usage:
h("hi");
ph("hi");
Foo::bar("hi");
qh("hi");
This is a functor:
class add_x {
int x;
public:
add_x(int x) : x(x) {}
int operator()(int y) { return x + y; }
};
And from main I can do this:
add_x add10(10); // create my functor
int i = add10(20); // add 20 and return it
How can I combine the functor with typedef?
For instance, I came across this:
typedef int (*myfuncType)(float f, char c1,char c2);
myfuncType pt2Function = NULL;
But what am I defining here exactly? operator ()?
Function pointer is - as its name says - just a pointer to function. You cannot use a pointer to function to point to functor, which is essentially a class with overloaded () operator.
You may be interested in std::function from C++11:
#include <functional>
(...)
std::function<int(int)> fn = add_x(10);
int i = fn(20);
Edit: Ok, I see, what you are asking for.
Maybe some code will make things clear.
int fn(float a, char b, char c) { ... }
(...)
typedef int (*myFuncType)(float f, char c1, char c2);
myFuncType ptrToFun = &fn;
(*fn)(1.0f, 'a', 'z');
This typedef creates a "pointer-to-function" type. If you declare a variable of this type, then you'll be able to assign to it a pointer to function (extracted with regular & operator) and - for example - pass to another function or just store (or call this function).
std::function is a lot more flexible, because you can store in it a pointer to function, a functor or even a lambda and call them normally.
I don't understand your first question (How can I combine the functor with typedef ?), so I can't answer that - a typedef would work as it would with any other class.
Regarding your second question: the line
typedef int (*myfuncType)(float f, char c1,char c2);
gives a name (myfunctType) to the type int (*)(float, char, char) (read: "a function which takes a float and two char values and then returns an int").
So
myfuncType pt2Function = NULL;
Defines a variable which can point to such an above-mentioned function, but sets the pointer to NULL for now.
Here, myfuncTypeis a type describing a pointer of function, with three float parameters and which return an int. A functor is just a class with operator() overload. So the typedef is used just like other class.
typedef add_x add will work.
I am trying to understand how to use functional pointers to map the method from instances in C++ like delegates in C#.
class FunctionalPointers
{
public:
static int IncrementCounter ( int *a, int b )
{
return *a += b;
}
int NonStaticIncrementCounter ( int *a, int b )
{
return *a += b;
}
};
//Declare a functional pointer as a separate type.
typedef int ( *AFunctionalPointer ) ( int*, int );
int _tmain(int argc, _TCHAR* argv[])
{
int a = 10;
int *ptr = &a;
*ptr = 200;
//This works as the methods are static
AFunctionalPointer funcInstance = FunctionalPointers::IncrementCounter;
int result = funcInstance( ptr, a );
//But if I try to make the same call from an
//instance of a non static method I get an error. Why ?
FunctionalPointers *functionalPointer = new FunctionalPointers();
//ERROR : Compiler says it's illegal operation.
AFunctionalPointer funcClassInstanceType = *functionalPointer->IncrementCounter;
int instanceResult = funcClassInstanceType( ptr, a );
return 0;
}
As you can see above, if a static method is assigned to the functional pointer it compiles perfectly but if I try to do the same thing with non static method with the instance of the class, the compiler throws an illegal operation error.
Mapping an instance method to a delegate in C# is very much possible like the snippet below
class Program
{
static void Main( string[] args )
{
int a = 200;
int b = a;
FunctionalPointer funcInstance = new FunctionalPointer();
AFunctionalPointer degegateInstance = funcInstance.Increment;
int result = degegateInstance( 200, 200 );
}
}
public delegate int AFunctionalPointer( int a, int b );
class FunctionalPointer
{
public int Increment ( int a, int b )
{
return a += b;
}
public int Decrement( int a, int b )
{
return a -= b;
}
}
My question is,
Is it a knowledge gap on my part or is it a part of the rule in C++ to define function pointers in a different way to support instance types.
C++ requires different pointer types for member functions. The C++ FAQ has a whole section on them.
You can get C#-like behavior by using the std::function wrapper from C++11.
Pointer to class member should be declared as:
int (ClassName::*FunctionPointer)(int, int);
Member pointers use different syntax. Here is your code modified to use it:
typedef int ( *AFunctionalPointer ) ( int*, int );
// Use this syntax to declare pointers to member functions
typedef int (FunctionalPointers::*InstFunctionalPointer) ( int*, int );
int main()
{
int a = 10;
int *ptr = &a;
*ptr = 200;
//This works as the methods are static
AFunctionalPointer funcStatic = FunctionalPointers::IncrementCounter;
int result = funcStatic( ptr, a );
InstFunctionalPointer funcInstance = FunctionalPointers::NonStaticIncrementCounter;
//Now when I try to make the same call from an
//instance of a non static method I don't get an error.
FunctionalPointers *functionalPointer = new FunctionalPointers();
// Use this syntax to call member functions through a member pointer
int instanceResult = (functionalPointer->*funcInstance)(ptr, a );
return 0;
}
Pointers to static member functions are essentially the same thing as pointers to functions. Pointers to non-static member functions, on the other hand, are completely different beasts, because they need an object on which to invoke that member function.
The C# expression funcInstance.Increment binds the object to the member function and gives you back something that can be called like a normal function. The C++ equivalent is:
#include <functional>
using namespace std::placeholders;
int main()
{
int a = 10;
int *ptr = &a;
*ptr = 200;
FunctionalPointers functionalPointer;
auto funcClassInstanceType = std::bind(
&FunctionalPointers::NonStaticIncrementCounter, functionalPointer, _1, _2);
int instanceResult = funcClassInstanceType( ptr, a );
}
Non-static methods are of a different type. And there's a good reason for that: they are supposed to operate on an instance of the class! You can declare a pointer to a non-static method as such
int (FunctionalPointers::*pointer_to_non_static_method)(int*, int)
= FunctionalPointers::NonStaticIncrementCounter;
But you will need an object to use it!
Another option is to overload the operator() in your class:
class FunctionalPointers {
...
int operator()(int* a, int b) { return *a += b; };
...
}
and you still need an object to use it:
FunctionalPointers f;
f(a,b);
You can't use a function pointer as a stateful delegate; instead, you need a class that overloads the function call operator, operator(). This can be called like a function and also hold state, such as a particular object on which to call a member function.
In C++11, one option is std::function:
typedef std::function<int(int*,int)> delegate;
using namespace std::placeholders;
FunctionalPointers fp; // no need for "new" here
delegate d = [&](int * p, int a){fp.IncrementCounter(p,a);};
int result = d(ptr, a);
In C++03, you can use boost::function and boost::bind to achieve the same thing, or write your own class with an overloaded operator(), along the lines of:
class Delegate {
public:
typedef int FunctionalPointers::*member_fn(int*,int);
Delegate(FunctionalPointers * fp, member_fn fn) : fp(fp), fn(fn) {}
int operator()(int * p, int a) {return (fp->*fn)(p,a);}
private:
FunctionalPointers * fp; // Object to call member function of
member_fn fn; // Member function to call
};
FunctionalPointers fp;
Delegate d(&fp, &FunctionalPointers::IncrementCounter);
int result = d(ptr, a);
although you'll need a bit more work still to get the polymorphic behaviour or std::function.
What would typedef int (&rifii) (int, int) be used for?
What is the typedef before this "statement" do?
I want to think of this as
typedef (int (&rifii) (int, int)) [new name]
but the [new name] is not there like if you do
typedef int INTEGER;
Similar question for the following syntax:
typedef void (*PF) ();
PF edit_ops[ ] = { &cut, &paste, ©, &search };
PF file_ops[ ] = { &open, &append, & close, &write };
PF* button2 = edit_ops;
PF* button3 = file_ops;
button2[2]( );
What is the typedef allowing? Is it making it so you don't have to type:
void (*PF) ();
(void (*PF) ()) edit_ops[ ] = { &cut, &paste, ©, &search };
(void (*PF) ()) file_ops[ ] = { &open, &append, & close, &write };
(void (*PF) ())* button2 = edit_ops;
(void (*PF) ())* button3 = file_ops;
If so what happend to the second part ([what you want]) of the typedef like in:
typedef [what you have -- (FP)] [what you want]
Clarification on this matter is greatly appreciated.
Typedef does not work like typedef [type] [new name]. The [new name] part does not always come at the end.
You should look at it this way: if [some declaration] declares a variable, typedef [same declaration] would define a type.
E.g.:
int x; declares a variable named x of type int -> typedef int x;
defines a type x as int.
struct { char c; } s; defines a variable named s of some struct type -> typedef struct { char c; } s; defines type s to be some struct type.
int *p; declares a variable named p of type pointer to int ->
typedef int *p; defines a type p as pointer to int.
And also:
int A[]; declares an array of ints named A -> typedef int A[]; declares a type A as an array of ints.
int f(); declares a function named f -> typedef int f(); declares a function type f as returning an int and taking no arguments.
int g(int); declares a function name g -> typedef int g(int); declares a function type g as returning an int and taking one int.
As an aside: Note that all function arguments come after the new name! As those types could be complicated as well, there can be a lot of text after the [new name]. Sadly, but true.
But those are not proper function pointers yet, just function types. I'm not sure a function type exists in C or C++, but it is useful as an intermediate step in my explanation.
To create a real function pointer, we have to add '*' to the name. Which, sadly, has wrong precedence:
typedef int *pf(); declares a function type pf as return a int*. Oops, that's not what was intended.
So use () to group:
typedef int (*pf)(); declares a function pointer type pf as returning an int and taking no arguments.
typedef int (&rf)(); declares a function reference type rf as returning an int and taking no arguments.
Let's now look at your examples and answer your questions:
typedef int (&rifii) (int, int); declares a function reference type rifii as returning an int and taking two int arguments.
And obviously (?) button2[2]( ); will call copy();.
Proper syntax without typedefs is hard to write correctly without a compiler, and hard to read even with a compiler:
void (*edit_ops[])() = { &cut, &paste, ©, &search };
void (*file_ops[])() = { &open, &append, & close, &write };
void (**button2)() = edit_ops;
void (**button3)() = file_ops;
button2[2]( );
Which is why everyone prefers typedefs when using function pointers.
When reading, find the place to start reading. Read as much to the right as you can, but observe the grouping by (). Then read to the left as much as you can, again limited by grouping (). After finishing everything inside the (), start with reading to the right, then to the left.
Applied to void (*edit_ops[])(), this means that
edit_ops is
(go to the right)
an array
(hit the end of the group, so turn to the left)
of pointer
(end of grouping)
to a function taking
(parse the () to the right)
no arguments
(go to the left)
returning a void
For the experts:
To make it even more complicated, arguments can have names (which will be ignored), so it might even be hard to find where to start parsing! E.g. typedef int (*fp)(int x); is valid and the same as typedef int (*fp)(int); Names can even have () around them: typedef int (*fp)(int (x)); But as we have seen, argument names can be left out, so even the following is allowed: typedef int (*fp)(int ());. This is still a function pointer taking a single int and return an int. In case you would like to make your code really hard to read...
edit: sorry first answer didn't initialize the fcn ptr.
typedef int (&rifii) (int, int) allows you to declare function pointers that return an int by reference and take two ints as parameters.
rifi x,y,z;
int &ret_an_int_ref( int p1, int p2 ) {
static int retval=0;
if( p1 > p2 ) retval = p1*p2;
return retval;
}
x = ret_an_int_ref;
y = ret_an_int_ref;
int & an_int_ref = x(1,2);
int & another_int_ref=y(3,4);
z = x;
z(1,2); // will give the same answer as x(1,2);