简体   繁体   中英

c++ passing function as argument to another function with void pointer

I'm trying to pass a function as argument to another function with void pointer and it doesn't work

#include <iostream>
using namespace std;

void print()
{
    cout << "hello!" << endl;
}

void execute(void* f()) //receives the address of print
{
    void (*john)(); // declares pointer to function
    john = (void*) f; // assigns address of print to pointer, specifying print returns nothing
    john(); // execute pointer
}

int main()
{
    execute(&print); // function that sends the address of print
    return 0;
}

The thing are the void function pointers, I could make an easier code like

#include <iostream>
using namespace std;

void print();
void execute(void());

int main()
{
    execute(print); // sends address of print
    return 0;
}

void print()
{
    cout << "Hello!" << endl;
}

void execute(void f()) // receive address of print
{
    f();
}

but I wonna know if I can use void pointers

it is for implement something like this

void print()
{
    cout << "hello!" << endl;
}

void increase(int& a)
{
    a++;
}

void execute(void *f) //receives the address of print
{
    void (*john)(); // declares pointer to function
    john = f; // assigns address of print to pointer
    john(); // execute pointer
}

int main()
{
    int a = 15;
    execute(increase(a));
    execute(&print); // function that sends the address of print
    cout << a << endl;
    return 0;
}

Using gcc test.cpp I get:

test.cpp: In function ‘void execute(void* (*)())’:
test.cpp:12:22: error: invalid conversion from ‘void*’ to ‘void (*)()’ [-fpermissive]
test.cpp: In function ‘int main()’:
test.cpp:18:19: error: invalid conversion from ‘void (*)()’ to ‘void* (*)()’ [-fpermissive]
test.cpp:9:6: error:   initializing argument 1 of ‘void execute(void* (*)())’ [-fpermissive]

The signature for the f argument is incorrect. You need to use

void execute(void (* f)())

instead. Therefore, you don't need the cast when assigning to john :

john = f

Also, you can simplify this by calling f directly:

f(); // execute function pointer

EDIT: Since you want to use void pointers, you need to pass f as a void pointer:

void execute(void *f)

Here, you will need the assignment to john , but as f is already a void * you don't need the cast.

NOTE: Given that you are passing a void pointer, the execute function will accept anything and you will have runtime errors if you pass the wrong thing. For example:

void print_name(const char *name)
{
    printf("%s", name);
}

void execute1(void *f);
void execute2(void (*f)());

int main()
{
    int value = 2;
    execute1(&value); // runtime crash
    execute1(&print_name); // runtime crash
    execute2(&value); // compile-time error
    execute2(&print_name); // compile-time error
}

Using a specifically defined function pointer lets the compiler generate an error at the point where you have passed the wrong argument type. This is preferred to crashing at runtime, as the runtime crash may be exploited as a security vulnerability and requires extensive testing to ensure this error does not occur.

Use

void execute(void (*f)()) //receives the address of print

Or better use:

void execute(boost::function<void()> const & f) //receives the address of print

To accept functors as well, or replace boost:: with std:: if you are using compiler which supports C++11

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM