How can I use this pointer with pointer to member function - c++

I have typedef for a function pointer:
typedef bool(WlanApiWrapper::* (connect_func) )(WLAN_AVAILABLE_NETWORK, const char *, const char *);
and have a method that returns a pointer to function:
const auto connect_method = map_algorithm_to_method(*network)
So I want to call that like that:
(*this.*connect_method)(*network, ssid, pass);
but gets error:
Error (active) E0315 the object has type qualifiers that are not compatible with the member function CppWlanHack C:\Projects\CppWlanHack\CppWlanHack\WlanApiWrapper.cpp 52
but when I call that like that:
WlanApiWrapper f;
(f.*connect_method)(*network, ssid, pass);
all is building...
How can I call the method without creating an object, because I've already had an object (this pointer)

The error message sounds to me like you're calling a non-const member function pointer inside a const member function. this is a const WlanApiWrapper * inside a const member function so the object (*this) has type qualifiers (const) that are not compatible with the (non-const) member function.
To solve this, you can either make the connect_method const or make the member function that contains (this->*connect_method)(*network, ssid, pass); non-const.

Call it like this:
((*this).*connect_method)(*network, ssid, pass);
This should work with all compilers.
For more info, read How can I avoid syntax errors when calling a member function using a pointer-to-member-function? in C++ FAQ

Related

invalid use of non-static member function in qsort C++

here is my function in class SuffixArray:
int pstrcmp(const void *a, const void *b) {
return strcmp((const char *)*(char **)a, (const char *)*(char **)b);
}
I used this comparison function in qsort:
qsort(ap, len1+len2, sizeof(char *),pstrcmp);
which ap is a pointer array of suffix
When I compile it, there is an error:
invalid use of non-static member function
and I use notepad++ to compile it, it provide that
error: cannot convert 'SuffixArray::pstrcmp' from type 'int (SuffixArray::)(const void*, const void*)' to type 'int (*)(const void*, const void*)'
qsort(ap, len1+len2, sizeof(char *),pstrcmp);
is there anyone can help me?
In C++ you need to pass a free-standing function or a static member function (as opposed to a non-static member function) to qsort, because calling conventions of non-static member functions require an instance to be passed.
You have two solutions to this problem:
Move the declaration of pstrcmp out of the SuffixArray class, or
Declare pstrcmp static in the class.

How to assign member function pointer to non-member function pointer? [duplicate]

I am trying to pass member function pointer to the c-style function (as it's lib in C)
The pointer it wants is defined as:
void (*)(int, const char*)
So the function I am trying to pass is:
void Application::onError(int error, const char *description)
I am trying to pass that with this code:
setCallback(bind(&Game::onError, this, placeholders::_1, placeholders::_2));
This gives me the following error:
cannot convert ‘std::_Bind_helper<false, void (Application::*)(Application*, int,
const char*), Application* const, const std::_Placeholder<1>&, const
std::_Placeholder<2>&>::type {aka std::_Bind<std::_Mem_fn<void (Application::*)
(Application*, int, const char*)>(Application*, std::_Placeholder<1>,
std::_Placeholder<2>)>}’ to ‘GLFWerrorfun {aka void (*)(int, const char*)}’ for
argument ‘1’ to ‘void (* glfwSetErrorCallback(GLFWerrorfun))(int, const char*)’
glfwSetErrorCallback(bind(&Application::onError, this, placeholders::_1, placeholders::_2));
Is there any way to successfully pass a member function as a bound function to the c-style function?
The result of std::bind is a complicated C++ object. It has to store all the bound arguments, for example. So it is most definitely not convertible to a pointer to function.
The callback specification you're dealing with apparently doesn't allow a "user data" payload, so there's nowhere to hide a pointer to a C++ object which you could use to invoke a non-static member funtion. This means you will have to call a global or static member function, or resort to a global/static member/per-thread variable to store the object pointer.
The only 100% portable way is to create a C linkage function to use as the callback. This does so, and uses a global object pointer to call your original onError():
Application *error_handling_application;
extern "C" void errorCallback(int error, const char *description)
{
error_handling_application->onError(error, description);
}
Note that quite often, you will encounter programs which use a static member function in place of my errorCallback. This works with most compilers on most platforms, but it is not guaranteed to work. The C library expects a function with C language linkage. A static member function can only have C++ language linkage. It is possible for the calling mechanism of a C function and a C++ function to differ (depends on ABI), which would result in a malformed call to the static member function passed in.
Since the member function also has the this pointer as implied argument, it is not of the type accepted by the C function. Hence, IMHO the only way is to generate a standalone function with C linkage
class A {
public: void func(int, const char*) const;
};
extern "C" {
void cfunc(void(*)(int, const char*));
void call_cfunc(const A*);
}
// in some source (non-header) file:
namespace {
const A*pa;
void afunc(int i, const char*s)
{ pa->func(i,s); }
}
void call_cfunc(const A*a)
{
pa = a;
cfunc(afunc);
}
Not directly, no. A C++ member function needs an implicit this pointer, which of course C has no idea about and won't pass.
The usual way around this is to introduce a "trampoline" as a class method, but perhaps there are prettier ways in more modern C++ variants.

Why pointer to non-const member function can't point const member function and opposite?

What is the reason why pointers to member functions, can't point to const member functions?
struct A {
void g() {};
void f() const {}
};
Later in code:
void (A::* fun)() = &A::f;
This code produces:
error: cannot convert ‘void (A::*)()const’ to ‘void (A::*)()’ in initialization
Of course it compiles with &A::g instead of &A::f.
In opposite situation:
void (A::* fun)() const = &A::g;
The error is:
error: cannot convert ‘void (A::*)()’ to ‘void (A::*)()const’ in initialization
The second case is rather clear. const pointer isn't expected to modify the object so it can't hold the function which does it. But why it's not possible to assign const member function to non-const member function as in the first case?
It looks like the rule for normal pointers where casting const to non-const would allow to modify the value, but I don't see the point here, where const-correctness is checked in function definition, before such assignment.
What is the reason why pointers to member functions, can't point to const member functions?
Because the const modifier is part of the function signature. Once you declare a function pointer, that function pointer can only be used to assign pointers to function that have the same function signature.
Non-static member functions have an extra hidden this parameter. Given the existence of that that extra hidden parameter, a non-static void A::f() const; behaves much like void A__f(const A *__this), and the behaviour you see for member functions models the behaviour for non-member functions.
void f(void *);
void (*pf)(const void *) = f; // also an error
As for whether it could break on any implementation, I suppose in theory, an implementation is permitted to read a void * parameter from a different register than a const void * parameter, and if so, the result of the conversion (were it valid) could not be used to call f properly. I have no idea why any implementor would make such a decision, and I don't know of any real implementation that does so, but it's one allowed by the standard.

How to initialize static function pointer with non-static class function when class initing?

Definition(Core.h):
static int (*foolink)(int*, char*, key*, key*);
Also redefined in Core.cpp. This code causing error:
foolink = this->step;
error:
Engine/Core.cpp:31: error: argument of type 'int (Core::)(int*, char*, key*, key*)' does not match 'int (*)(int*, char*, key*, key*)'
Pointer using:
(*foolink)(NULL, NULL, NULL, NULL);
What's wrong? Please help me!
In C++ programs, most functions are member functions; that is, they are part of a class. You are not allowed to use an ordinary function pointer to point to a member function; instead, you have to use a member function pointer.
In your case, you can define it as
v you have to name the class here
int (YourClass::*foolink)(int*, char*, key*, key*);
foolink = &YourClass::step;
// This is how you can call the function via member function pointer
YourClass object, *pObject = &object;
// One way is to envoke the function from object
(object.*foolink)(...);
// The other way is from pointer to object
(pObject->*foolink)(...);
C++ FAQ:
Pointers to Member Functions
The type of this->step must be a function returning an integer and taking an int*, char*, key* and key* as arguments. It's obviously not. And remember, assigning class methods to normal functions won't work; they both have to be methods, or both normal functions, but not a mix, which is what I suspect you're trying to do.

No matching function for call (expects reference to pointer instead of pointer)

I get the error from xcode (3.2.4)/gcc(4.0):
/Users/admin/scm/audacity/mac/../src/toolbars/DeviceToolBar.cpp: In member function 'void DeviceToolBar::ShowInputDialog()':
/Users/admin/scm/audacity/mac/../src/toolbars/DeviceToolBar.cpp:817: error: no matching function for call to 'DeviceToolBar::ShowComboDialog(wxChoice*&, wxString)'
/Users/admin/scm/audacity/mac/../src/toolbars/DeviceToolBar.h:74: note: candidates are: void DeviceToolBar::ShowComboDialog(wxChoice*, wxString&)
So it looks like it expects a reference to a pointer in ShowComboDialog, but I don't know why as the signatures are clearly normal pointers. Furthermore if it was expecting a reference to a pointer the way I am calling it should work.
This is the first error, and there are no special warnings before it.
Also, this compiles in MSVC 2008 express.
Please give me a clue.
//in the class def
//(only relevant portions included
class DeviceToolBar:public ToolBar {
public:
DeviceToolBar();
virtual ~DeviceToolBar();
void ShowInputDialog();
private:
void ShowComboDialog(wxChoice *combo, wxString &title);
wxChoice *mInput;
};
//in the cpp file
void DeviceToolBar::ShowInputDialog()
{
ShowComboDialog(mInput, wxString(_("Select Input Device")));
}
void DeviceToolBar::ShowComboDialog(wxChoice *combo, wxString &title)
{
//...
}
The problem is not the first parameter; its the second. You're passing in a temporary wxString, but the function is expecting a reference. C++ will automatically convert a temporary to a const reference, but it cannot convert it to a reference. You need to make ShowComboDialog take a const reference as its second parameter.
Your ShowComboDialog takes a wxString by non-const reference and you are trying to pass a temporary object as an argument to this parameter. You can only bind const references to temporary objects.
You either need to change ShowComboDialog to take its second argument either by value (wxString) or by const reference (const wxString&) or you need to create a variable for the wxString that you create when you call the function and then pass (a reference to) that variable instead.