how to create queue that will hold pointer to function? - c++

I try to make queue that can receive pointer to function - and i can't find how to do it
this is my code
struct TaskElement
{
int id;
std::function<void()> func;
void operator()()
{
func();
}
};
int main()
{
MyMath* myMathElement = new MyMath();
myMathElement->Print_1();
Queue<TaskElement> myQueue;
TaskElement t1;
t1.id = 1;
t1.func = myMathElement->Print_1;
TaskElement t2;
t2.id = 2;
t2.func = &myMathElement->Print_2;
myQueue.push(t1); Error !!! &': illegal operation on bound member function expression
myQueue.push(t2); Error !!! &': illegal operation on bound member function expression
auto rec1 = myQueue.pop();
rec1();
std::cin.get();
}

Non-static member functions needs an object to be called on. By using plain myMathElement->Print_1 you're not providing any object, just a pointer to a member function.
Either use std::bind to provide the object as the first argument to the function:
t1.func = std::bind(&MyMath::Print_1, myMathElement);
Or use lambda expressions:
t1.func = [myMathElement]() { myMathElement->Print_1(); };
As for your errors, either you get them because of some problem in the Queue class (which you haven't shown us), but more likely the errors doesn't come from the push calls but rather from the assignments to the func member.
You should get them from the assignment because they are not valid assignments. You can't use member functions like that, you must use the address-of operator & and full scoping with the class (or structure) instead of an object. As shown above with the std::bind call, you must use &MyMath::Print_1.

Related

Pass a C++ member function as a callback function [duplicate]

I am using luabind as my lua to C++ wrapper. Luabind offers a method to use my own callback function to handle exceptions thrown by lua, set_pcall_callback(). So I paraphrased an example from the documentation, the changes being the logger->log() function and putting the function in a class called 'Engine', so instead of it being a regular global function it is now a member function, which is where my problem seems to be.
Here are the relevant code snips:
class Engine //Whole class not shown for brevity
{
public:
Engine();
~Engine();
void Run();
int pcall_log(lua_State*);
private:
ILogger *logger;
};
Engine::Run()
{
lua_State* L = lua_open();
luaL_openlibs(L);
open(L);
luabind::set_pcall_callback(&Engine::pcall_log); //<--- Problem line
//etc...rest of the code not shown for brevity
}
int Engine::pcall_log(lua_State *L)
{
lua_Debug d;
lua_getstack( L,1,&d);
lua_getinfo( L, "Sln", &d);
lua_pop(L, 1);
stringstream ss;
ss.clear();
ss.str("");
ss << d.short_src;
ss << ": ";
ss << d.currentline;
ss << ": ";
if ( d.name != 0)
{
ss << d.namewhat;
ss << " ";
ss << d.name;
ss << ") ";
}
ss << lua_tostring(L, -1);
logger->log(ss.str().c_str(),ELL_ERROR);
return 1;
}
Here is what the compiler says during compilation:
C:\pb\engine.cpp|31|error: cannot convert 'int (Engine::*)(lua_State*)' to 'int (*)(lua_State*)' for argument '1' to 'void luabind::set_pcall_callback(int (*)(lua_State*))'|
So it seems that the error is that the function expects a regular function pointer, not a class member function pointer. Is there a way to cast or use an intermediate function pointer to pass to the set_pcall_callback() function?
Thank you!
No. A member function is not a free function. The type is entirely different, and a pointer to a member function (PTMF) is a completely different, incompatible object from a function pointer. (A PTMF is usually much bigger, for example.) Most importantly a pointer-to-member must always be used together with an instance pointer to the object whose member you want to call, so you cannot even use a PTMF the same way you use a function pointer.
The easiest solution for interacting with C code is to write a global wrapper function that dispatches your call, or to make your member function static (in which case it becomes essentially a free function):
// global!
Engine * myEngine;
int theCallback(lua_State * L)
{
return myEngine->pcall_log(L);
}
Engine::Run()
{
/* ... */
myEngine = this;
luabind::set_pcall_callback(&theCallback);
/* ... */
}
The conceptual problem here is that you have an engine class, although you will practically only have one single instance of it. For a genuine class with many objects, a PTMF wouldn't make sense because you'd have to specify which object to use for the call, whereas your engine class perhaps is essentially a singleton class which could be entirely static (i.e. a glorified namespace).
Not suitable for your LUA problem, but maybe on other libraries:
If a function requests a a function pointer like func(void* param, ...) and you can ensure that the lifetime of your object is greater than the stored function pointer, then you could technically also use a method pointer (looks the same on the stack), but C++ prevents direct casting of method pointers to function pointers.
But with a little trick, you can also cast method pointers to function pointers:
template<typename M> inline void* GetMethodPointer(M ptr)
{
return *reinterpret_cast<void**>(&ptr);
}
Using that, you can use method pointers for example with libmicrohttpd:
this->m_pDaemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, this->m_wPort, NULL, NULL, reinterpret_cast<MHD_AccessHandlerCallback>(GetMethodPointer(&CMyWebServer::AccessHandlerCallback)), this, MHD_OPTION_END);
But be aware of it. You must take care of the lifetime of that object. Also the calling conventions must match.
As a callback, it is usual to use static functions:
class Engine //Whole class not shown for brevity
{
....
static int pcall_log(lua_State*);
...
}
This would solve your issue.
Explicit conversion from method pointer to function pointer is illegal in C++ - period.
But there is a hack. We have to first convert the (const) method pointer to (const) void* and then to (const) function pointer. And it works. And why wouldn't it? Everything and I mean everything can be pointed to by a void* because everything has an address.
WARNING: The below is DAAEINGEROUS hack territory. If you're developing software for a fighter jet or whatnot, you should know better than to use this. I'm not responsible! I'm just providing this here for educational purposes.
The trick is we must convert between method pointer and function pointer through an intermediate conversion to, potentially cv (const-volatile) qualified, void*.
This way we are able to call a member function (pointer) through a function pointer, with the first argument being a Type* pointer to the target class object, which is equivalent to the member function call's this*.
Given a:
MethodPointerType f;
then
FunctionPointerType m_pFn = reinterpret_cast<FunctionPointerType>( reinterpret_cast<void*&>( f ) );
or to make it more explicit use two of the following in sequence, for non-const and const member functions:
template<typename MP>
void* getMethodVoidPointer( MP ptr )
{
return *reinterpret_cast<void**>( &ptr );
}
template<typename FP>
FP getFunctionPointer( void* p )
{
return reinterpret_cast<FP>( p );
}
template<typename MP>
const void* getMethodConstVoidPointer( MP ptr )
{
return *reinterpret_cast<const void**>( &ptr );
}
template<typename FP>
FP getConstFunctionPointer( const void* p )
{
return reinterpret_cast<FP>( p );
}
Play with it live here with a complete compilable sample in C++17: https://onlinegdb.com/HybR8crqw
It works in Visual Studio too.

Obtaining a function pointer to a non static member function

Suppose I have a class:
class A {
public:
A();
void myFunc();
};
Then at a different point in the program I create an instance of class A, and attempt to obtain a function pointer to myFunc():
A* a = new A;
//ATTEMPTS AT RETRIVING FUNCTION POINTER FOR A::MYFUNC
std::function<void()> fnptr = a->myFunc;
std::function<void()> fnptr(std::bind(A::myFunc, &a);
But both of these attempts present the error "call to non static member function without object argument"
Perhaps both of these attempts are totally off the mark, but essentially im trying to obtain a function pointer to the myFunc() function in the specific instance of a. Any help on how to do so is appreciated :)
I'm trying to obtain a function pointer to the myFunc() function
Obtaining a pointer to member function for A::myFunc() can be done:
void (A::*memFuncPtr)() = &A::myFunc;
or even better, taking advantage of auto:
auto memFuncPtr = &A::myFunc;
However, to dereference this pointer (i.e., to call the member function it points to), you will eventually need an A object. This object corresponds to the one the member function will be called on.
You can dereference the pointer to member function, memFuncPtr, either in combination with an A object and the .* operator:
A a;
a.*memFuncPtr();
or in combination with a pointer to an A object and the operator ->*:
A *aPtr = new A();
aPtr->*memFuncPtr();
As a result, you would need to keep a reference to the object or a copy of it in order to create std::function<void()> out of this pointer to member function.
std::invoke
Since C++17, you can simply use the std::invoke() function template instead of .* / ->*. It unifies the syntax for the two cases exposed above:
std::invoke(memFuncPtr, a);
std::invoke(memFuncPtr, aPtr);
You need the following syntax:
std::function<void()> fnptr(std::bind(&A::myFunc, a));
You could also use a lambda expression like this:
auto fn = [a] { a->myFunc(); };
Here's a demo.

Pointer to function wrong conversion [duplicate]

I am using luabind as my lua to C++ wrapper. Luabind offers a method to use my own callback function to handle exceptions thrown by lua, set_pcall_callback(). So I paraphrased an example from the documentation, the changes being the logger->log() function and putting the function in a class called 'Engine', so instead of it being a regular global function it is now a member function, which is where my problem seems to be.
Here are the relevant code snips:
class Engine //Whole class not shown for brevity
{
public:
Engine();
~Engine();
void Run();
int pcall_log(lua_State*);
private:
ILogger *logger;
};
Engine::Run()
{
lua_State* L = lua_open();
luaL_openlibs(L);
open(L);
luabind::set_pcall_callback(&Engine::pcall_log); //<--- Problem line
//etc...rest of the code not shown for brevity
}
int Engine::pcall_log(lua_State *L)
{
lua_Debug d;
lua_getstack( L,1,&d);
lua_getinfo( L, "Sln", &d);
lua_pop(L, 1);
stringstream ss;
ss.clear();
ss.str("");
ss << d.short_src;
ss << ": ";
ss << d.currentline;
ss << ": ";
if ( d.name != 0)
{
ss << d.namewhat;
ss << " ";
ss << d.name;
ss << ") ";
}
ss << lua_tostring(L, -1);
logger->log(ss.str().c_str(),ELL_ERROR);
return 1;
}
Here is what the compiler says during compilation:
C:\pb\engine.cpp|31|error: cannot convert 'int (Engine::*)(lua_State*)' to 'int (*)(lua_State*)' for argument '1' to 'void luabind::set_pcall_callback(int (*)(lua_State*))'|
So it seems that the error is that the function expects a regular function pointer, not a class member function pointer. Is there a way to cast or use an intermediate function pointer to pass to the set_pcall_callback() function?
Thank you!
No. A member function is not a free function. The type is entirely different, and a pointer to a member function (PTMF) is a completely different, incompatible object from a function pointer. (A PTMF is usually much bigger, for example.) Most importantly a pointer-to-member must always be used together with an instance pointer to the object whose member you want to call, so you cannot even use a PTMF the same way you use a function pointer.
The easiest solution for interacting with C code is to write a global wrapper function that dispatches your call, or to make your member function static (in which case it becomes essentially a free function):
// global!
Engine * myEngine;
int theCallback(lua_State * L)
{
return myEngine->pcall_log(L);
}
Engine::Run()
{
/* ... */
myEngine = this;
luabind::set_pcall_callback(&theCallback);
/* ... */
}
The conceptual problem here is that you have an engine class, although you will practically only have one single instance of it. For a genuine class with many objects, a PTMF wouldn't make sense because you'd have to specify which object to use for the call, whereas your engine class perhaps is essentially a singleton class which could be entirely static (i.e. a glorified namespace).
Not suitable for your LUA problem, but maybe on other libraries:
If a function requests a a function pointer like func(void* param, ...) and you can ensure that the lifetime of your object is greater than the stored function pointer, then you could technically also use a method pointer (looks the same on the stack), but C++ prevents direct casting of method pointers to function pointers.
But with a little trick, you can also cast method pointers to function pointers:
template<typename M> inline void* GetMethodPointer(M ptr)
{
return *reinterpret_cast<void**>(&ptr);
}
Using that, you can use method pointers for example with libmicrohttpd:
this->m_pDaemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, this->m_wPort, NULL, NULL, reinterpret_cast<MHD_AccessHandlerCallback>(GetMethodPointer(&CMyWebServer::AccessHandlerCallback)), this, MHD_OPTION_END);
But be aware of it. You must take care of the lifetime of that object. Also the calling conventions must match.
As a callback, it is usual to use static functions:
class Engine //Whole class not shown for brevity
{
....
static int pcall_log(lua_State*);
...
}
This would solve your issue.
Explicit conversion from method pointer to function pointer is illegal in C++ - period.
But there is a hack. We have to first convert the (const) method pointer to (const) void* and then to (const) function pointer. And it works. And why wouldn't it? Everything and I mean everything can be pointed to by a void* because everything has an address.
WARNING: The below is DAAEINGEROUS hack territory. If you're developing software for a fighter jet or whatnot, you should know better than to use this. I'm not responsible! I'm just providing this here for educational purposes.
The trick is we must convert between method pointer and function pointer through an intermediate conversion to, potentially cv (const-volatile) qualified, void*.
This way we are able to call a member function (pointer) through a function pointer, with the first argument being a Type* pointer to the target class object, which is equivalent to the member function call's this*.
Given a:
MethodPointerType f;
then
FunctionPointerType m_pFn = reinterpret_cast<FunctionPointerType>( reinterpret_cast<void*&>( f ) );
or to make it more explicit use two of the following in sequence, for non-const and const member functions:
template<typename MP>
void* getMethodVoidPointer( MP ptr )
{
return *reinterpret_cast<void**>( &ptr );
}
template<typename FP>
FP getFunctionPointer( void* p )
{
return reinterpret_cast<FP>( p );
}
template<typename MP>
const void* getMethodConstVoidPointer( MP ptr )
{
return *reinterpret_cast<const void**>( &ptr );
}
template<typename FP>
FP getConstFunctionPointer( const void* p )
{
return reinterpret_cast<FP>( p );
}
Play with it live here with a complete compilable sample in C++17: https://onlinegdb.com/HybR8crqw
It works in Visual Studio too.

How to cast std::make_unique so that I can use the functions declared in the class?

Or do I need to cast std::make_unique into any forms at all?
I have a FOO class with some functions that I can use:
FOO::FOO(const yoo &yoo, float numbers) :
num_to_execute(numbers)
{
...
...
}
void FOO::execute()
{
execute(num_to_execute);
}
In another .cpp, my given codes initated foo using the following method:
new_foo = std::make_unique<FOO>(yoo, number);
(up until now everything is correct). What I want to do is to call execute on my new_foo. I tried with
new_foo.execute();
But it says:
error: 'class std::unique_ptr<WORK::TOBEDONE::FOO>' has no member named 'EXECUTE'
execute should be able to called on member <WORK::TOBEDONE::FOO> but the std::unique_ptr is giving me a hard time to understand what I should do.
new_foo->execute();
unique_ptr behaves like a regular pointer in that sense, and has a operator-> and operator * overloaded.
you use a regular dot (.) to access unique_ptr functions (like std::unique_ptr::get) while using -> and * to access the pointee.
auto str = std::make_unique<std::string>("hello world");
auto i = std::make_unique<int>(5);
str->size();
*i = 4;
str.reset(); //deletes the pointee and make str point to null
i.reset(); //as above

C++ class member function pointer to function pointer

I am using luabind as my lua to C++ wrapper. Luabind offers a method to use my own callback function to handle exceptions thrown by lua, set_pcall_callback(). So I paraphrased an example from the documentation, the changes being the logger->log() function and putting the function in a class called 'Engine', so instead of it being a regular global function it is now a member function, which is where my problem seems to be.
Here are the relevant code snips:
class Engine //Whole class not shown for brevity
{
public:
Engine();
~Engine();
void Run();
int pcall_log(lua_State*);
private:
ILogger *logger;
};
Engine::Run()
{
lua_State* L = lua_open();
luaL_openlibs(L);
open(L);
luabind::set_pcall_callback(&Engine::pcall_log); //<--- Problem line
//etc...rest of the code not shown for brevity
}
int Engine::pcall_log(lua_State *L)
{
lua_Debug d;
lua_getstack( L,1,&d);
lua_getinfo( L, "Sln", &d);
lua_pop(L, 1);
stringstream ss;
ss.clear();
ss.str("");
ss << d.short_src;
ss << ": ";
ss << d.currentline;
ss << ": ";
if ( d.name != 0)
{
ss << d.namewhat;
ss << " ";
ss << d.name;
ss << ") ";
}
ss << lua_tostring(L, -1);
logger->log(ss.str().c_str(),ELL_ERROR);
return 1;
}
Here is what the compiler says during compilation:
C:\pb\engine.cpp|31|error: cannot convert 'int (Engine::*)(lua_State*)' to 'int (*)(lua_State*)' for argument '1' to 'void luabind::set_pcall_callback(int (*)(lua_State*))'|
So it seems that the error is that the function expects a regular function pointer, not a class member function pointer. Is there a way to cast or use an intermediate function pointer to pass to the set_pcall_callback() function?
Thank you!
No. A member function is not a free function. The type is entirely different, and a pointer to a member function (PTMF) is a completely different, incompatible object from a function pointer. (A PTMF is usually much bigger, for example.) Most importantly a pointer-to-member must always be used together with an instance pointer to the object whose member you want to call, so you cannot even use a PTMF the same way you use a function pointer.
The easiest solution for interacting with C code is to write a global wrapper function that dispatches your call, or to make your member function static (in which case it becomes essentially a free function):
// global!
Engine * myEngine;
int theCallback(lua_State * L)
{
return myEngine->pcall_log(L);
}
Engine::Run()
{
/* ... */
myEngine = this;
luabind::set_pcall_callback(&theCallback);
/* ... */
}
The conceptual problem here is that you have an engine class, although you will practically only have one single instance of it. For a genuine class with many objects, a PTMF wouldn't make sense because you'd have to specify which object to use for the call, whereas your engine class perhaps is essentially a singleton class which could be entirely static (i.e. a glorified namespace).
Not suitable for your LUA problem, but maybe on other libraries:
If a function requests a a function pointer like func(void* param, ...) and you can ensure that the lifetime of your object is greater than the stored function pointer, then you could technically also use a method pointer (looks the same on the stack), but C++ prevents direct casting of method pointers to function pointers.
But with a little trick, you can also cast method pointers to function pointers:
template<typename M> inline void* GetMethodPointer(M ptr)
{
return *reinterpret_cast<void**>(&ptr);
}
Using that, you can use method pointers for example with libmicrohttpd:
this->m_pDaemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, this->m_wPort, NULL, NULL, reinterpret_cast<MHD_AccessHandlerCallback>(GetMethodPointer(&CMyWebServer::AccessHandlerCallback)), this, MHD_OPTION_END);
But be aware of it. You must take care of the lifetime of that object. Also the calling conventions must match.
As a callback, it is usual to use static functions:
class Engine //Whole class not shown for brevity
{
....
static int pcall_log(lua_State*);
...
}
This would solve your issue.
Explicit conversion from method pointer to function pointer is illegal in C++ - period.
But there is a hack. We have to first convert the (const) method pointer to (const) void* and then to (const) function pointer. And it works. And why wouldn't it? Everything and I mean everything can be pointed to by a void* because everything has an address.
WARNING: The below is DAAEINGEROUS hack territory. If you're developing software for a fighter jet or whatnot, you should know better than to use this. I'm not responsible! I'm just providing this here for educational purposes.
The trick is we must convert between method pointer and function pointer through an intermediate conversion to, potentially cv (const-volatile) qualified, void*.
This way we are able to call a member function (pointer) through a function pointer, with the first argument being a Type* pointer to the target class object, which is equivalent to the member function call's this*.
Given a:
MethodPointerType f;
then
FunctionPointerType m_pFn = reinterpret_cast<FunctionPointerType>( reinterpret_cast<void*&>( f ) );
or to make it more explicit use two of the following in sequence, for non-const and const member functions:
template<typename MP>
void* getMethodVoidPointer( MP ptr )
{
return *reinterpret_cast<void**>( &ptr );
}
template<typename FP>
FP getFunctionPointer( void* p )
{
return reinterpret_cast<FP>( p );
}
template<typename MP>
const void* getMethodConstVoidPointer( MP ptr )
{
return *reinterpret_cast<const void**>( &ptr );
}
template<typename FP>
FP getConstFunctionPointer( const void* p )
{
return reinterpret_cast<FP>( p );
}
Play with it live here with a complete compilable sample in C++17: https://onlinegdb.com/HybR8crqw
It works in Visual Studio too.