2

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)'

4
  • 7
    Use std::function and std::bind instead. Commented Oct 28, 2016 at 7:13
  • 1
    As for your error, member function are not the same as non-member functions. Member functions need an instance of an object to be called, non-member functions don't. That object instance is often passed as a hidden argument to the member function, and since non-member function won't have that hidden argument they are simply not compatible in any way, shape or form. Commented Oct 28, 2016 at 7:16
  • 2
    as an alternative to bind you can also use a lamba where you call the member function and store it in a std::function object. Commented Oct 28, 2016 at 7:23
  • another thing, which makes this whole a bit more unclear. What are you trying to do? you cannot set a function pointer to a class which has no instance when it is not static. You need an instantiation. Do you want a static function pointer or a default one? Commented Oct 28, 2016 at 7:30

2 Answers 2

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; 
}
Sign up to request clarification or add additional context in comments.

8 Comments

Good point. Didn't notice the "non-static" in the title. I'll amend.
I knew that was possible being static, but i wanted to know if possible doing non-static. thanks a lot for help.
What you had wasn't possible with static. I've updated for non-static.
It is the only solution quickly, i do frame as the solution, @Martin Bonner please you can tell me if it's possible declare it out of the class, something like x::gv = Rtx; (out of the class).?
... which is a long way of saying "No, you can't write x::gv = Rtx outside the class for a non-static member". @nikomaster
|
1

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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.