-1

I am a somewhat rusty programmer, and new to C++. I've been asked to write a program that can pass a pointer to a function into another function and execute. I can make the simple case work, where everything is in a .cpp file. But when I place the code in a class inside a .h file it won't compile. I am either code blind or missing something.

Here is the code that works:

/*
 *  funcptr.cpp
 *
 *  Example:
 *  - pass function pointer as argument
 *  - execute passed function
 */
#include <stdio.h>

void takes_a_function(void (*f)(void *data), void *data);
void print_char(void *data);
void print_int(void *data);

// This function gets passed (to takes_a_function)
void print_char(void *data) {
  char *ch = (char *)data;
  printf("%c\n", *ch);
}

// This function gets passed (to takes_a_function)
void print_int(void *data) {
  int *i = (int *)data;
  printf("%d\n", *i);
}

void takes_a_function(void (*f)(void *), void *data) {
    //f(data);    // this also works
    (*f)(data);
}

int main() {

  int i = 100;
  takes_a_function(print_int, &i);

  char ch = 'A';
  takes_a_function(print_char, &ch);

}

It compiles and runs:

# g++ funcptr.cpp -o funcptr
# ./funcptr
100
A

So far so good. But then I put the code into a .h file and "class"-ify it so I can use it from anywhere, and everything falls apart:

#ifndef __funcptr_h__
#define __funcptr_h__

#include <stdio.h>

void takes_a_function(void (*f)(void *data), void *data);
void print_char(void *data);
void print_int(void *data);
void testit();

class FunctionPtr
{
    public:

    // This function gets passed (to takes_a_function)
    void print_char(void *data) {
        char *ch = (char *)data;
        printf("%c\n", *ch);
    }

    // This function gets passed (to takes_a_function)
    void print_int(void *data) {
        int *i = (int *)data;
        printf("%d\n", *i);
    }

    void takes_a_function(void (*f)(void *a), void *data) {
          //f(data);        // this also works
          (*f)(data);
    }

    void testit() {
        int i = 100;
        takes_a_function(print_int, &i);

        char ch = 'A';
        takes_a_function(print_char, &ch);
    }

};

#endif

The compiler error is:

# g++ funcptr.h
funcptr.h: In member function ‘void FunctionPtr::testit()’:
funcptr.h:34:33: error: invalid use of non-static member function ‘void FunctionPtr::print_int(void*)’
   takes_a_function(print_int, &i);
                                 ^
funcptr.h:22:7: note: declared here
  void print_int(void *data) {
       ^~~~~~~~~
funcptr.h:37:35: error: invalid use of non-static member function ‘void FunctionPtr::print_char(void*)’
   takes_a_function(print_char, &ch);
                                   ^
funcptr.h:16:7: note: declared here
  void print_char(void *data) {
   ^~~~~~~~~~

I've been playing with this for a while and done a fair amount of reading on passing function pointers, including on StackOverflow, however all the examples I see are simple and of no help.

Any insights are much appreciated. Thanks to all.

mvwhyatt
  • 465
  • 1
  • 6
  • 9
  • 3
    This is not a pointer to a function anymore ... it is a **pointer to member function** ... [read up on that](https://isocpp.org/wiki/faq/pointers-to-members). – donkopotamus Jul 22 '17 at 23:25
  • 2
    `#define __funcptr_h__` that is a reserved symbol, so defining it has undefined behaviour. – eerorika Jul 22 '17 at 23:34
  • [What are the rules about using an underscore in a C++ identifier?](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) – user4581301 Jul 22 '17 at 23:48

1 Answers1

-1

It looks to me like your problem is when you call takes_a_function with your arguments. You declared the data parameter as a pointer to a void type, not a reference to a void type. You could try something like:

void testIt() {
    int i = 100;
    int * j = &i;
    takes_a_function(print_int, j);
    char c = 'a';
    char * d = &c;
    takes_a_function(print_char, d);
};

References and pointers are not exactly the same thing.

Also it looks like you forgot a #endif after you define __funtptr_h__

I hope this helped

mike bayko
  • 375
  • 5
  • 20