Reputation: 7203
I have this simple code:
#include <iostream>
using namespace std;
class GenericMove {};
class SwapMove: public GenericMove {};
class SoftConstraint {
public:
virtual int evaluate(GenericMove& gm) = 0;
};
class M1: public SoftConstraint {
public:
int evaluate(GenericMove& gm){ return 1; }
int evaluate(SwapMove& gm){ return 2; }
};
int main () {
M1 m1;
GenericMove* swapmove = new SwapMove();
cout << "Hello " << m1.evaluate(*swapmove) << endl;
return 0;
}
I would like to discern between GenericMove and SwapMove in the evaluate
function of M1 , so I would like that the main prints "Hello 2".
Is there a way to distinguish that swapmove
is not only a simple GenericMove but it is also SwapMove inside M1?
Is that possible in C++? Thanks in advance!
Upvotes: 0
Views: 49
Reputation: 1779
No, this is not directly possible in C++ AFAIK, but you can use double dispatch to achieve your desired result.
class GenericMove;
class SwapMove;
class SoftConstraint {
public:
virtual int evaluate(GenericMove& move) = 0;
virtual int evaluate(SwapMove& move) = 0;
};
class M1 : public SoftConstraint {
public:
int evaluate(GenericMove& move) { return 1; }
int evaluate(SwapMove& move) { return 2; }
};
class GenericMove {
public:
virtual int evaluate(SoftConstraint& constraint) {
return constraint.evaluate(*this);
}
};
class SwapMove : public GenericMove {
public:
int evaluate(SoftConstraint& constraint) {
return constraint.evaluate(*this);
}
};
int main () {
M1 m1;
GenericMove* swapmove = new SwapMove();
std::cout << "Hello " << swapmove->evaluate(m1) << std::endl;
return 0;
}
Note that in my proposal you have to call the evaluate
method of the move instance as opposed to calling the evaluate
method of the constraint. But this could be changed easily.
Double dispatch exploits the fact that the static type of the this
pointer is always the type to which the function using the this
pointer belongs. In our example, the static type of this
in GenericMove::evaluate
is GenericMove*
, so the call to SoftConstraint::evaluate
selects the function that takes a reference to an instance of GenericMove
as its argument. On the other hand, the static type of this
in SwapMove::evaluate
is SwapMove*
, so the call to SoftConstraint::evaluate
selects the function that takes a reference to an instance of SwapMove
as its argument.
Double dispatch allows you to select a method using the type of the receiver of the call and the type of one argument.
Upvotes: 1