简体   繁体   中英

C++ method pointer call yields undefined symbol error?

I would like to have a class that has a method pointer that points to one of two possible methods of the same class. I use Embarcadero XE2 bcc32 for this.

When I try the following, I get the Error E2451 Undefined symbol findPosition :

class A{
    public:
        double (A::*findPosition)(std::vector<int> arr, int tresh); //method pointer
        double mean(std::vector<int> arr, int tresh){return 0;};               //case 1
        double median(std::vector<int> arr, int tresh){return 0;};             //case 2
        A(){findPosition=&(A::mean);}                               //constructor set pointer to case 1
};
int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<int> vals(5,1);   // 1 1 1 1 1, example input

    A obj;
    obj.findPosition=&(A::median);   //set method pointer to case 2
    (obj.*findPosition)(vals,0);     //ERROR: E2451 Undefined symbol 'findPosition'

    system("pause");
}

Is (obj.*findPosition)(vals,0) not the correct version of a method-pointer call? Should I use boost:bind perhaps? Or is this generally a bad idea and I should stick to something like

class A{
    public:
        int flag;
        double findPosition(std::vector<int> arr, int tresh){
            if(flag==0)return mean(arr,tresh);
            else if(flag==1)return median(arr,tresh);
        };
        double mean(std::vector<int> arr, int tresh){return 0;};               //case 1
        double median(std::vector<int> arr, int tresh){return 0;};             //case 2
        A(){flag=0;}                               //constructor set use to case 1
};

The .* and ->* operators are defined as follows:

expression .* expression
expression ->* expression

Where the right-hand expression must evaluate to a pointer that is pointing to a member within the object specified by the left-hand expression.

The code fails to compile because you are trying to pass in a non-existent local variable for the right-hand expression. That missing variable is what the compiler is complaining about.

You need something more like this instead:

(obj.*obj.findPosition)(vals,0);

Or, more clearer:

(obj.*(obj.findPosition))(vals,0);

Or, more verbose:

double (A::*fp)(std::vector<int>, int) = obj.findPosition;
(obj.*fp)(vals,0);

That being said, if you are not worried about portability to other compilers, you can use BCC's __closure extension instead:

class A{
    public:
        double (__closure *findPosition)(std::vector<int> arr, int tresh); //method pointer
        double mean(std::vector<int> arr, int tresh){return 0;};               //case 1
        double median(std::vector<int> arr, int tresh){return 0;};             //case 2
        A(){findPosition=&mean;}                               //constructor set pointer to case 1
};

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<int> vals(5,1);   // 1 1 1 1 1, example input

    A obj;
    obj.findPosition=&(obj.median);   //set method pointer to case 2
    obj.findPosition(vals,0);

    system("pause");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM