MindLerp
MindLerp

Reputation: 378

Class non-static method pointer to global function

I'm trying to point a class method to a global function, i've seen this
but how i can't do it without instance?.

Consider this:

class x
{
    public:
        int(x::*GetVal)(int);
};

int RtX(int a)
{
    return a * 4;
}

// declaration
int(x::*GetVal)(int) = (int(x::*)(int))&::Rtx; // :: global? // error

int main()
{
    x a;
    cout << (a.*GetVal)(4) << endl; 
}

This returns me the error:

[Error] invalid cast from type 'int ()(int)' to type 'int (x::)(int)'

Upvotes: 2

Views: 555

Answers (2)

Bruno V.
Bruno V.

Reputation: 29

Non static member functions need an instance in order to be called. You might consider using a static function member instead and if you also use std::function, you might get a simple code to assign your member function without instance:

#include <iostream>
#include <functional>

int RtX(int a)
{
    return a * 4;
}

class x
{
public:
    static std::function<int(int)> GetVal;
};

std::function<int(int)> x::GetVal = RtX;

int main()
{
    x a;
    std::cout << (a.GetVal)(4) << std::endl;
}

Upvotes: 1

x::GetX is a pointer to member. These are deeply complicated beasts, and you can't get them to point to non-member functions. The following code will work:

#include <iostream>

int RtX(int a)   // Global non-member function
{
    return a * 4;
}

class x
{
    public:

        int(x::*GetVal)(int);

        // This is an instance member function which acts as a proxy and calls the
        // the global function
        int RtX(int a) { return ::RtX(a); }
};


int main()
{
    x a;
    a.GetVal =&x.RtX;  // Assign the member variable.  Could do this in the
                       // constructor.  **NOTE** No casts!
    std::cout << (a.*GetVal)(4) << std::endl; 
}

If you find yourself reaching for a cast when dealing with function pointers and pointers-to-member-functions, stop - you are almost certainly doing it wrong, and while it will compile, it is very likely not to run properly.

Alternatively, as noted in the comments, use std::function.

#include <iostream>
#include <functional>

int RtX(int a)
{
    return a * 4;
}

class x
{
public:
    std::function<int(int)> GetVal;

    // Initialize GetVal in the constructor.
    x() : GetVal(RtX) 
    {}

    // Alternatively, you can initialize the variable in with a default
    // initialization.  You can also declare the member const if you don't want to 
    // change it later.

    const std::function<int(int)> gv = RtX;

    /*
};

int main()
{
    x a;
    std::cout << a.GetVal(4) << std::endl; 
}

Upvotes: 1

Related Questions