I will like to know, how to make a function where I define a function. And then I can call the defined function. Let me try with a example.
void funcToCall() {
std::cout<<"Hello World"<<std::endl;
}
void setFuncToCall(void func) {
//Define some variable with func
}
void testFuncCall() {
//Call function that has been defined in the setFuncToCall
}
setFuncToCall(funcToCall()); //Set function to call
testFuncCall(); //Call the function that has been defined
I Hope that you understand what I am trying to do here. But I don't know how to bring It down to the right code :-)
You need a function pointer. It's easier to work with function pointers if you typedef them first.
typedef void (*FuncToCallType)();
FuncToCallType globalFunction; // a variable that points to a function
void setFuncToCall(FuncToCallType func) {
globalFunction = func;
}
void testFuncCall() {
globalFunction();
}
setFuncToCall( funcToCall ); //Set function to call,NOTE: no parentheses - just the name
testFuncCall(); //Call the function that has been defined
As other answers have suggested you can use objects like functions, too. But this requires operator overloading (even if it remains hidden from you) and is typically used with templates.
It gives more flexibility (you can set some state to the object before passing it to the function and the object's operator() can use that state) but in your case function pointers may be just as good.
What you want to use is a callback, and is has been answered her : Callback functions in c++
I would advise you to use std::tr1::function ( generalized callback )
C syntax for function pointers is a bit weird, but here we go:
// this is a global variable to hold a function pointer of type: void (*)(void)
static void (*funcp)(void);
// you can typedef it like this:
//typedef void (*func_t)(void);
// - now `func_t` is a type of a pointer to a function void -> void
// here `func` is the name of the argument of type `func_t`
void setFuncToCall(void (*func)(void)) {
// or just: void setFuncToCall(func_t func) {
//Define some variable with func
...
funcp = func;
}
void testFuncCall(void) {
//Call function that has been defined in the setFuncToCall
funcp();
}
setFuncToCall(funcToCall); // without () !
testFuncCall();
Related
In Windows/MSVS/C++ I can get a function pointer by pointing to its name like this:
void foo()
{
auto fooPtr = &foo;
}
But can I do the same thing without knowing the name of the function?
void foo()
{
auto fnPtr = &thisFunction; //no
}
Use case: I want to define a macro I can put at the top of many functions which will declare a pointer to the function. Ex:
#define defFnPtr auto fnPtr = &thisFunction
void foo()
{
defFnPtr;
}
void bar()
{
defFnPtr;
}
No, there is no way in standard C++ to get a pointer to the "current" function.
Best that you could do is perhaps to use meta programming: Write a program that generates the line auto fnPtr = &foo; into the source.
That said, I don't think that the goal is worth the effort.
I have grouped several member functions into an array. How do I access a function from the array? I am getting 'error C2064: term does not evaluate to a function taking 0 arguments.' See below.
class A
{
public:
//Constructor
A()
{
//Fill function array
ClipFunction[0] = &A::ClipTop;
ClipFunction[1] = &A::ClipBottom;
ClipFunction[2] = &A::ClipLeft;
ClipFunction[3] = &A::ClipRight;
}
//Declare array
typedef void (A::*ClipFunction_ptr) ();
ClipFunction_ptr ClipFunction[4];
//Clipping functions
void ClipTop();
void ClipBottom();
void ClipLeft();
void ClipRight();
//Start clipping process
void StartClip();
};
//Define clipping functions
void A::ClipTop() {}
void A::ClipBottom() {}
void A::ClipLeft() {}
void A::ClipRight() {}
//Define A::StartClip()
void A::StartClip()
{
//Run through all functions in the array
for (unsigned int i = 0; i < 4; i++)
{
ClipFunction[i](); //ERROR. How do I access ClipFunction[i] ???
}
}
You need to dereference the function like this:
this->(*ClipFunction[i])();
What you're missing is the this or rather the compiler is complaining that it doesn't have the first parameter (the instance of the object invoking the member function) to pass it to the function.
To the compiler the member function:
void A::ClipFunction()
{
}
translates to something like:
void ClipFunction(A* this)
{
}
Hence the error complaining that the function is not one that takes zero arguments.
I think the problem is that you need use "this" explicitly as in http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/topic/com.ibm.xlcpp8l.doc/language/ref/cplr034.htm .
So in your case, you should use
(this ->* ClipFunction[i]) ();
instead of
ClipFunction[i]();
PS
When I reply this post, I didn't see Vite Falcon's answer. Basically we are saying the same thing but I don't think his code " this->(*ClipFunction[i])()" will compile because GCC gives errors on my machine. "(this->*ClipFunction[i])()" is the correct form.
I don't think you want the scope resolution operator :: in your typedef. Instead try putting
typedef void (*ClipFunction_ptr) ();
i'm trying to create a new thread with a class "CameraManager" but i have the following error:
cannot convert '*void(CameraManager:: * )(void*) to void*( * )(void*) in pthread_create function
i defined in the cameramanager.h file:
public:
void *dequeueLoop(void *ptr);
and in the cameramanager.cpp
void CameraManager::startDequeuing(){
dequeuing = true;
dequeueThreadId = pthread_create(&dequeueThread, NULL, &CameraManager::dequeueLoop, NULL);
}
void *CameraManager::dequeueLoop(void *ptr){
while(dequeuing){
highSpeedCamera->dequeue();
highSpeedCamera->enqueue();
}
I don't want to declare dequeueLoop as a static function i also tried to declare dequeueLoop as a class friend function in the following way but then it doesn't have scope on class variables 'highSpeedCamera' and 'dequeuing' and the compiler also tell me that 'dequeueLoop' was not declared in this scope
to make dequeueLoop a friend function i did:
cameramanager.h
public:
friend void *dequeueLoop(void *ptr);
cameramanager.cpp
void CameraManager::startDequeuing(){
dequeuing = true;
dequeueThreadId = pthread_create(&dequeueThread, NULL, &CameraManager::dequeueLoop, NULL);
}
void *dequeueLoop(void *ptr){
while(dequeuing){
highSpeedCamera->dequeue();
highSpeedCamera->enqueue();
}
}
Where i'm doing wrong?
I don't want to declare dequeueLoop as a static function
If you want to use pthreads, then you'll need a static or non-member function for the entry point. You can pass a pointer to your object to this function, using it as a trampoline into the non-static member function:
static void * dequeueEntry(void * self) {
return static_cast<CameraManager*>(self)->dequeueLoop();
}
dequeueThreadId = pthread_create(
&dequeueThread, NULL,
&CameraManager::dequeueEntry, // <-- pointer to trampoline function
this); // <-- pointer to object for member function
Alternatively, if you have a modern compiler, you could use the standard thread library instead:
std::thread thread(&CameraManager::dequeLoop, this);
If you want the function to be a member of the class, it must be static. It's because the thread function will be called directly and will not have a valid this pointer. This can be solved by having a wrapper function, that gets passed the actual object and then calls the proper member function:
void *dequeueLoopWrapper(void *p)
{
CameraManager *cameraManager = static_cast<CameraManager*>(p);
camereraManager->dequeueLoop();
return nullptr;
}
// ...
void CameraManager::startDequeuing()
{
dequeuing = true;
dequeueThreadId = pthread_create(&dequeueThread, NULL, dequeueLoopWrapper, this);
}
However, I would recommend you start using the threading support in the new standard library:
void CameraManager::startDequeuing()
{
dequeuing = true;
myThread = std::thread(&CameraManager::dequeueLoop, this);
}
You can't use a pointer to member function as a function pointer unless it's static. You'll have to make dequeueLoop a free function, or write a free function as a wrapper to it.
To access the class members in a free function, you should have the function pass it's this pointer as the final argument of pthread_create. Then have the free function cast it's argument to a pointer to the class.
I would like someone to shed some light this code snippet, which confuses me.
//-------------------------------------------------------------------------------
// 3.5 Example B: Callback to member function using a global variable
// Task: The function 'DoItB' does something that implies a callback to
// the member function 'Display'. Therefore the wrapper-function
// 'Wrapper_To_Call_Display is used.
#include <iostream.h> // due to: cout
void* pt2Object; // global variable which points to an arbitrary object
class TClassB
{
public:
void Display(const char* text) { cout << text << endl; };
static void Wrapper_To_Call_Display(char* text);
/* more of TClassB */
};
// static wrapper-function to be able to callback the member function Display()
void TClassB::Wrapper_To_Call_Display(char* string)
{
// explicitly cast global variable <pt2Object> to a pointer to TClassB
// warning: <pt2Object> MUST point to an appropriate object!
TClassB* mySelf = (TClassB*) pt2Object;
// call member
mySelf->Display(string);
}
// function does something that implies a callback
// note: of course this function can also be a member function
void DoItB(void (*pt2Function)(char* text))
{
/* do something */
pt2Function("hi, i'm calling back using a global ;-)"); // make callback
}
// execute example code
void Callback_Using_Global()
{
// 1. instantiate object of TClassB
TClassB objB;
// 2. assign global variable which is used in the static wrapper function
// important: never forget to do this!!
pt2Object = (void*) &objB;
// 3. call 'DoItB' for <objB>
DoItB(TClassB::Wrapper_To_Call_Display);
}
Question 1: Regarding this function call:
DoItB(TClassB::Wrapper_To_Call_Display)
Why does Wrapper_To_Call_Display not take any arguments, although it is supposed to take a char* argument according to its declaration?
Question 2: DoItB is declared as
void DoItB(void (*pt2Function)(char* text))
What I’ve understood so far is that DoItB takes a function pointer as argument, but why does the function call DoItB(TClassB::Wrapper_To_Call_Display) take TClassB::Wrapper_To_Call_Display as argument even tough it’s not a pointer?
Thanx in advance
Source of code snippet: http://www.newty.de/fpt/callback.html
In C/C++ when a function name is used with no parameters - that is no parenthesis - it is a pointer to a function. So TClassB::Wrapper_To_Call_Display is a pointer to the address in memory where the code for the function is implemented.
Since TClassB::Wrapper_To_Call_Display is a pointer to a void function that takes a single char* it's time is void (*)(char* test) so it matches the type required by DoItB.
I have a class Test with a peculiar data structure.
A member of class Test is a std::map where the key is a std::string and the mapped value is a struct defined as follows:
typedef struct {
void (Test::*f) (void) const;
} pmf_t;
Initialization of the map is OK. The problem is when I am trying to call the function pointed. I made up a toy example reproducing the problem. Here it is:
#include <iostream>
#include <map>
using namespace std;
class Test;
typedef void (Test::*F) (void) const;
typedef struct {
F f;
} pmf_t;
class Test
{
public:
Test () {
pmf_t pmf = {
&Test::Func
};
m["key"] = pmf;
}
void Func (void) const {
cout << "test" << endl;
}
void CallFunc (void) {
std::map<std::string, pmf_t>::iterator it = m.begin ();
((*it).second.*f) (); // offending line
}
std::map<std::string, pmf_t> m;
};
int main ()
{
Test t;
t.CallFunc ();
return 0;
}
Thanks in advance,
Jir
The name of the pmf_t type is f, so the first change is to remove the * to get second.f. That gives you a pointer-to-member value. To use a pointer-to-member, you need an instance. The only one you have available of the correct type is this, so use it with the ->* operator:
(this->*it->second.f)();
You need parentheses around the whole thing, or else the compiler thinks you're trying to call it->second.f() (which isn't allowed) and then applying the result to ->*.
The offending line is trying to call a member function without any object to call it on. If the intention is to call it for the this object, I believe the call should look like
( this->* ((*it).second.f) )();
Where this->* is the syntax for dereferencing a pointer-to-member for the current object. ((*it).second.f) is the pointer retrieved from the map, and () is the call operator for actually calling the function.
This is perhaps good as an exercise, but otherwise of limited use.
I think you might want to check out the C++ FAQ on this one. The syntax is apparently pretty tricky to get right (they actually recommend using a macro).
It might be too late for this question but, the seemingly complex synatax can be break down to two simple lines so it looks pretty clear:
void CallFunc (void)
{
pmf_t t = m["key"]; //1>get the data from key
(this->*t.f)(); //2>standard procedure to call pointer to member function
}
try this:
(this->*((*it).second.f)) ();