I've tried this declaration:
using fp_type = void (*)(fp_type);
Unsurprisingly, it does not work.
a.cpp: In function 'int main()':
a.cpp:13:26: error: expected ';' before '(' token
using fp_type = void(*)(fp_type);
^
a.cpp:13:34: error: expected primary-expression before ')' token
using fp_type = void(*)(fp_type);
Is there a workaround? I was thinking about a reinterpret_cast from a dummy function pointer type, but I am not sure how standard-compliant that is. I am looking into this because I don't want to capture a lambda in a ::std::function, and then use it recursively. I'd like to pass it a function pointer to itself.
5.2.10/6 guarantees you can reinterpret_cast a function pointer to a function pointer of different type, and when you cast it back to the original type, you get back the original pointer value.
I would prefer this:
void foo (struct foo_wrapper&);
struct foo_wrapper {
void (*pf) (struct foo_wrapper&);
// add constructor and accessor for convenience
};
Related
In the below given code snippet, when i wrote f = A; then why doesn't A decay to a pointer to a function?
//Func is alias for "pointer to a function that returns an int and does not take any parameter"
typedef int (*Func)();
int A(){
return 1;
}
int main()
{
Func* f = &A;//cannot convert ‘int (*)()’ to ‘int (**)()’ in initialization - I UNDERSTAND THIS ERROR
f = A;//error: cannot convert ‘int()’ to ‘int (**)()’ in assignment - My QUESTION IS THAT IN THIS CASE WHY DOESN'T "A" decay to a pointer to a function and give the same error as the above
}
I know why Func *f = &A; produces error. But i expected f = A; to produce the same error because i thought in this case A will decay to a pointer to a function and hence should produce the same error as Func*f = &A;. To be precise, i thought i would get the error
error: cannot convert ‘int(*)()’ to ‘int (**)()’ in assignment
But to my surprise, there is no decay and i do not get the above error.
Why/How is this so? That is, why is there no decay.
why doesn't A decay to a pointer to a function?
The error message says that a function (int()) cannot be implicitly converted to a pointer to a pointer to a function (int (**)()), because the type of the expression (A) is a function.
The function would decay if there was a valid conversion sequence to the target type through the decayed type. But there isn't such conversion sequence, and so the program is ill-formed.
I'd like to store a function pointer to a private member function of my object inside my class.
Basically I want to do this:
MyWindow::MyWindow()
{
std::function<void(int&)> func = this->memberFunction; // ERROR
}
void MyWindow::memberFunction(int& i)
{
// do something
}
When I try to build it the compiler throws an error:
Error C3867: 'MyWindow::memberFunction': non-standard syntax; use '&' to create a pointer to member
The error message for C3867 tells you the first problem: you need to use & to form a function pointer.
Your next problem is that you do not have a function pointer, but a pointer-to-member-function, and that is not compatible with your std::function, which is missing anywhere to store or pass the implicit first argument that holds the "this" pointer.
You can, however, "bind" a value for that argument, in effect hardcoding it into the functor.
You're also going to need to spell it MyWindow::memberFunction rather than this->memberFunction, because that's just the way it is (to quote GCC: "ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function").
So:
using std::placeholders;
std::function<void(int&)> func = std::bind(&MyWindow::memberFunction, this, _1);
Or, using modern techniques:
std::function<void(int&)> func = [this](int& x) { memberFunction(x); };
Or just:
auto func = [this](int& x) { memberFunction(x); };
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.
Here's a good example: I'm trying to overload OpenGL's glutMouseFunc so it may accept the namespace, and class function of my choosing. The one in particular is Init::DisplayInit::mouse, which is static. The question is, is this possible? If so, how is this achieved?
My Implementation
void glutMouseFunc(void (Init::DisplayInit::*mouse)(int, int, int, int)) {
(*mouse);
}
Errors from Implementation
..\OpenGL_03\/displayinit.h:27: error: variable or field 'glutMouseFunc' declared void
..\OpenGL_03\/displayinit.h:27: error: expected primary-expression before 'int'
..\OpenGL_03\/displayinit.h:27: error: expected primary-expression before 'int'
..\OpenGL_03\/displayinit.h:27: error: expected primary-expression before 'int'
..\OpenGL_03\/displayinit.h:27: error: expected primary-expression before 'int'
..\OpenGL_03\/displayinit.h:27: error: void value not ignored as it ought to be
Note, I put the declaration of the function in the same file's header file. I also made sure both the declaration and the definition of the function resided outside of the namespace declaration (which wraps most of both files, each). As shown, one of the first errors reads the function as a variable or field (???).
That's not a reasonable way to define glutMouseFunc. It isn't supposed to call the callback immediately, it's supposed to save a pointer for later (when mouse activity occurs).
Call the GLUT-provided version, and pass the address of your function:
#include <GL/glut.h>
glutMouseFunc(&Init::DisplayInit::mouse);
Static member functions are compatible with ordinary function pointers.
The answer to the headline question is "Yes; functions can accept static function pointers as arguments".
You don't specify the namespace or class in the pointer to function argument specification in the function using it:
void glutMouseFunc(void (*mouse)(int, int, int, int)) {
(*mouse)(1, 2, 3, 4);
}
You do specify the namespace or class in the invocation of the function:
glutMouseFunc(Init::DisplayInit::mouse);
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.