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