Home > Net >  Why I can't use pointer to a function
Why I can't use pointer to a function

Time:12-16

There is an objects with field double (A :: *ptrToFunc)(); Object B has got A; Can't use it in objects B.

class Foo
{
public:
    
    double (Foo :: *ptrToFunc)();
    
private:
    double func1();
    double func2();
    
public:
    Foo() : ptrToFunc{ &Foo::func1 } {}
}

class B
{
public:
    Foo obj();
    double countVal()
    {
        return (obj.*ptrToFunc)();  // use of undeclared identifier ptrToFunc
        return (obj.ptrToFunc)();  // called object (..) not a function or function pointer
    }
}

int main()
{
    B obj_B;
    double var = obj_B.countVal();
    return 0;
}

I have read C Tutorial: Pointer-to-Member Function but it doesn't help me.

CodePudding user response:

There are 2 problems with your code.

Problem 1

Foo obj(); is a member function declaration and not a data member declaration because of vexing parse (note the absence of "most"). That is, Foo obj(); declares a member function named obj with no parameter and return type Foo.

To solve this, replace it with:

//-----vv--->use braces
Foo obj{};

Problem 2

The second problem is that the syntax return (obj.*ptrToFunc)(); is incorrect as obj.ptrToFunc refers to the pointer and we still need to use that pointer on an object (as shown below).

To solve this 2nd problem, replace it with:

(obj.*(obj.ptrToFunc))() // or same as (obj.*obj.ptrToFunc)() 

Working demo


With , you can make the code more readable by using std::invoke:

double countVal()
{
//--------------vvvvvv--------------------->use invoke
    return std::invoke(obj.ptrToFunc, obj); 
}

Demo c 17

CodePudding user response:

Another slightly different way to solve the issues pointed out by the accepted answer. I rather like std::invoke from 'functional' than can call whatever is callable without too much trouble.

Also made the code self contained to make it easy to try it for future readers.

#include <iostream>
#include <functional> class Foo { public:
    
    double (Foo::*ptrToFunc)();
     private:
    double func1() { return 1.0;}
    double func2() { return 2.0;}
     public:
    Foo() : ptrToFunc{&Foo::func2} {} };

class B { public:
    Foo obj = Foo();
    double countVal()
    {
        return std::invoke(obj.Foo::ptrToFunc, obj);       
    } };

int main() {
    B obj_B;
    double var = obj_B.countVal();
    std::cout << var << std::endl;
    return 0; }
  • Related