Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

funtion pointer



  • hi there,

    i'm trying to relearn function pointers "again" and i need some help.
    this is my class:

    class test
    {
    public:
        test();
        void test2();
        ~test();
    
        int origin;
    
        int * number;
        void (test:: *foo)(void);
    
    };
    
    void test::test2(){
        std::cout << "hi" <<std::endl;
    }
    
    

    this is my Main():

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        test first;
    
        first.foo = &test::test2; // compiles
       //first.foo = &first.test2; // does not complile
    
        first.foo(); // <-- i wanna call my newly configured function pointer.
    
        return a.exec();
    }
    

    these are the errors:

    main.cpp:19: error: called object type 'void (test::*)()' is not a function or function pointer
    main.cpp:19: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘first.test::foo (...)’, e.g. ‘(... ->* first.test::foo) (...)’
       19 |     first.foo();
          |               ^
    

    kind regards

    why?

    void (test:: *foo)(void);
    

    and not

    static void (*foo)(void);
    

    [Moved to C++ Gurus ~kshegunov]


  • Qt Champions 2017

    @Natural_Bugger said in funtion pointer:

    int main(int argc, char *argv[])
    {
        // ...
        test first;
        first.foo = &test::test2; //< Assigning an address to a pointer is correct, so it compiles
        // first.foo = &first.test2;  //< Makes no sense `test2` isn't a member variable or a function call, so it can't be accessed with `.`
    
        (first.*(first.foo))(); //< Call a method through a PMF
        // ...
    }
    

    these are the errors:

    main.cpp:19: error: called object type 'void (test::*)()' is not a function or function pointer
    main.cpp:19: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘first.test::foo (...)’, e.g. ‘(... ->* first.test::foo) (...)’
       19 |     first.foo();
          |               ^
    

    See the comments above.

    why?

    void (test:: *foo)(void);
    

    and not

    static void (*foo)(void);
    

    Static functions are no different from global functions, with the exception of their scope. So a static function has the same prototype as a global, that is:

    class A
    {
        static void x();
    };
    
    void y();
    
    decltype(&A::x) //< void (*)();
    decltype(y) //< void (*)();
    

    Methods on the other hand need to have an object to be called upon, hence they're bound to a specific instance of a specific class. Thus the prototype of a method must specify also the class it belongs to (low-level details are unimportant here):

    class A
    {
        void z();
    };
    
    decltype(&A::z) //< void (A::*)();
    


  • @kshegunov

    Thnx a lot, for your comprehensive reply.

    how about if you create the function pointer locally and point to a member of a class.
    if i stated that correctly.

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
         test first;
    
        void (*foo)(void);
        foo = &test::test2;
    
    
        return a.exec();
    }
    
    returns:
    

    main.cpp:22: error: assigning to 'void ()()' from incompatible type 'void (test::)()'
    main.cpp:22: error: cannot convert ‘void (test::)()’ to ‘void ()()’ in assignment
    22 | foo = &test::test2;
    | ^~~~~



  • @kshegunov

    now i'm trying to create a function pointer that takes an argument and returns a value.

    test.h:

    class test
    {
    public:
        test();
    
        void test2();
        int test3(int a);
    
        ~test();
    
        void (test:: *foo)(void);
        int (test:: *foo2)(int);
        int (test:: *foo3)();
    
    };
    
    #endif // TEST_H
    

    test.cpp:

    .
    ..
    ...
    void test::test2(){
        std::cout << "hi" <<std::endl;
    }
    
    int test3(int a){
    return a;
    }
    
    int test4(){
    return 10;
    }
    

    main:

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        test first;
    
        first.foo = &test::test2;
        (first.*(first.foo))();
    
        first.foo2 = &test::test3; // <--- error
        (first.*(first.foo2))(10);
    
       first.foo3 = &test::test4; <--- error
        std::cout << "Foo: " + std::to_string((first.*(first.foo3))) <<std::endl; <---error
    
        return a.exec();
    }
    

    error:

    main.cpp:27: error: undefined reference to `test::test3(int)'
    
    first.foo3 = &test::test4; // <--- error, with the next line commented.
    //std::cout << "Foo: " + std::to_string((first.*(first.foo3))) <<std::endl;
    
    // uncommented, it doesn't show an error on that line, but on line:
    // std::cout << "Foo: " + std::to_string((first.*(first.foo3))) <<std::endl;
    main.cpp:31: error: invalid use of non-static member function of type ‘int (test::)()’
       31 |     std::cout << "Foo: " + std::to_string((first.*(first.foo3))) <<std::endl;
          |                                           ~~~~~~^~~~~~~~~~~~~~~
    main.cpp:31: error: reference to non-static member function must be called; did you mean to call it with no arguments?
    

    i tried:

    first.foo2 = &test::test3(int); 
    

    but results is more errors:

    main.cpp:27: error: call to non-static member function without an object argument
    main.cpp:27: error: expected '(' for function-style cast or type construction
    main.cpp:27: error: expected primary-expression before ‘int’
       27 |     first.foo2 = &test::test3(int);
          |                               ^~~
    

    kind regards


  • Lifetime Qt Champion

    @Natural_Bugger said in funtion pointer:

    int test3(int a){

    int test::test3(int a){
    


  • @jsulm

    ay, i didn't notice..
    thanks alot.


Log in to reply