What does this mean: warning: converting from ‘void (ClassName::*)()’ to ‘void (*)()’ - c++

I have a member function in a class that has a callback, but the callback isn't strictly neccessary, so it has a default callback, which is empty. It seems to work fine, but I get an annoying warning:
warning: converting from ‘void (ClassName::*)()’ to ‘void (*)()’
I'm trying to figure out what it means and how to turn it off (or fix it if I really am doing something wrong). Here's some simple code:
class ClassName{
public:
void doSomething(void (*callbackFunction)() = (void(*)()) &ClassName::doNothing){
callbackFunction();
}
void doNothing(){}
};
int main(){
ClassName x;
x.doSomething();
return 0;
}
Note: If I do this (without explicitly casting it as a void(*)()):
void doSomething(void (*callbackFunction)() = &ClassName::doNothing)
I get this:
main.cpp:3: error: default argument for parameter of type ‘void (*)()’ has type ‘void (ClassName::*)()’

The issue is that you're passing a pointer to an instance method rather than a static method. If you make doNothing a static method (which means no implicit instance argument), the warning goes away.
Specifically,
warning: converting from ‘void (ClassName::*)()’ to ‘void (*)()’
exactly is saying that it's converting from a member function of class ClassName, to a non-member function.
See also the C++ FAQ Lite entry about pointers to member functions and pointers to functions.

Free function pointer is not the same as class member function pointer, which requires an instance of the class at call site. Though a static member function will do.

Related

How does member-function understand that the object is obtained by dereferencing a const pointer?

I created a const pointer which points to an instance of abject allocated dynamically.I could not understand the object itself is const or not.
Firstly I tried to call a non-const member function by using pointer, as expected it caused a compile error because (it is my explanation, don't know if it is true or not) this pointer created by the member function is assigned to that const pointer. It did not yield anything.
Secondly I tried to dereference the pointer and call that non-const member function. I thought that the this pointer created by member function now will not be a const pointer because compile can not know the object returned by p (namely *p) is returned by a const pointer or not. It turns out that I was mistaken.
How does member-function understand that ?
#include<iostream>
class A
{
int a=4;
public:
A()
{}
void print()
{
std::cout<<a<<std::endl;
}
};
int main()
{
const A* p = new A();
p->print(); //1 causes compile error
(*p).print(); //2 causes compile error
return 0;
}
I thought the line labelled as 2 will not create a compile error.
It causes a compile error.The error message is:
"a.cpp: In function ‘int main()’:
a.cpp:21:13: error: passing ‘const A’ as ‘this’ argument discards qualifiers [-fpermissive]
p->print(); //1 causes compile error
^
a.cpp:10:9: note: in call to ‘void A::print()’
void print()
^~~~~
a.cpp:22:15: error: passing ‘const A’ as ‘this’ argument discards qualifiers [-fpermissive]
(*p).print(); //2 causes compile error
^
a.cpp:10:9: note: in call to ‘void A::print()’
void print()
^~~~~
Variables have types and can therefore be const or non-const, but expressions have types too. The type of (*p) is const A, and you can't call a non-const method of a const type.
There is no difference between (1) and (2). (1) is syntax sugar for (2).
You should define the print method as const in order to call it for const object.
void print() const { ... }
As it has already been noted, expressions have types and the type of (*p) is const A. You cannot call a non-const function on an object of a const type but you can call const member function. Member functions can have a const qualifier which will mark them to be able to be invoked on const objects or pointers to const objects.
void print() const
{
std::cout<<a<<std::endl;
}
This will make your code compile. and it looks like this is what you intended to do anyway.

Shadowing a member function with a function argument

Take the following class for an example
class A
{
int m_c;
public:
void B(int C);
void C();
};
This would give out the following warning if i compiled with the -Wshadow argument
memberFuncArg.cpp: In member function ‘void A::B(int)’:
memberFuncArg.cpp:12:16: warning: declaration of ‘C’ shadows a member of 'this' [-Wshadow]
void A::B(int C)
^
What are the consequences of shadowing a member function with an argument to another member function like this?
What are the consequences of shadowing a member function with an argument
The consequence is that a programmer who reads the code may be confused about which entity is being referred to by C. They may have become accustomed to the fact that C is a member function, and reasonably (but mistakenly) expect this to be the case within B as well.
The consequence is much worse when the argument is not of type int, but of some other type that can be invoked with same arguments as the member function. The confused programmer would then read or write C() and expect it to call the member function, but the behaviour would be different than expected.

How do I create and use a functionpointer with alternativ parameterlist in c++ class

back with another function pointer question ;)
I want to create a function pointer in my class that can point to different functions with have different parameterlists. That is I want a functionpointer that can point to and call all of the below functions (with its resp parameters).
funct1 takes a function pointer and
calls func2 with a pointer to func3,
func2 calls func3
In the C-code they are declared as:
typedef int (*FUNCTION)();
int func1(long sec, FUNCTION func, int argc, long *argv);
int func2(FUNCTION func);
int func3();
and called like this
func1(b->argv[0], func2, 3, arglist){ func(func3); }
Now I have created a class cDP5 to hold those methods and the function pointer
I've declared like this
typedef int(cDP5::*FUNCTION)(int *fc, char *buf, int sz);
but get compilation errors on this call
func1(b->argv[0], func2, 3, arglist);
receive this error:
cDP5.cpp:725:48: error: no matching function for call to ‘cDP5::func1(long&, <unresolved overloaded function type>, int, long int [3])’
cDP5.cpp:725:48: note: candidate is:
In file included from cDP5.cpp:11:0:
cDP5.h:96:9: note: int cDP5::func1(long int, cDP5::FUNCTION, int, long int*)
cDP5.h:96:9: note: no known conversion for argument 2 from ‘<unresolved overloaded function type>’ to ‘cDP5::FUNCTION {aka int (cDP5::*)(int*, char*, int)}’
OK I think if I try to make a FUNCTION cast like this then
func1(b->argv[0], (cDP5::FUNCTION)func2, 3, arglist);
but then I get this error:
cDP5.cpp:725:45: error: cannot convert ‘cDP5::func2’ from type ‘int (cDP5::)(int, long int*)’ to type ‘cDP5::FUNCTION {aka int (cDP5::*)(int*, char*, int)}’
Any ideas how to create and use the wanted functionpointer inside a c++ class?
Or do I need to create one for each parameterlist?
OK, based on what Schiff has mentioned and my own research I've found that it is not possible to create one function pointer that take multiple paremeterlists.
I have to create functionpointer for each parameterlist.
Though there is an option to use template paramters that I found in template function pointer parameter in a class method That I think would eas up the parameter types somewhat ;)

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 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.