I would like to be able to check whether a certain condition is true or not on an object of some Derived
type, which in the local context is only known through its Base
type.
The condition to be checked needs specific knowledge of the Derived
type, but I'm trying to achieve a level of indirection that allows the checking to be done in a context which only knows about the base class.
One possible way of doing this is by encapsulating the information needed for the check in a functor (or lambda) and dispatch it to the place where the check needs to be performed.
Define the classes
class Base {
//...
public:
using Condition = std::function<bool(const Base*)>;
bool check(const Condition&);
}
class DerivedA : public Base {
//...
public:
int index() const { return index;}
private:
int index;
}
class DerivedB : public Base {
//...
public:
std::string name() const { return name;}
private:
std::string name;
}
and suppose we have a Derived
-aware context, where I can encapsulate the the Derived
-specific condition in a lambda function. We can then dispatch the Condition
functor to the context where it is going to be needed:
//context where DerivedA and DerivedB are known
int idx = 1;
auto derivedCondition = [idx](const Base* obj) {
DerivedA* derivedObj = dynamic_cast<const DerivedA*>(obj);
if (derivedObj)
return (derivedObj->index() == idx);
return false;
};
std:string str = "Peter";
auto derivedCondition = [str](const Base* obj) {
DerivedB* derivedObj = dynamic_cast<const DerivedB*>(obj);
if (derivedObj)
return (derivedObj->name() == str);
return false;
};
// dispatch condition to an external context where it will be used, this context is not aware of Derived
useConditionElsewhere(derivedCondition);
with
void useConditionElsewhere(Condition condition) {
//context where only base class is known
Base* baseObj;
//... suppose baseObj is created from a factory class that returns a random subclass
// baseObj can be a DerivedA, DerivedB or none of them
bool checked = baseObj->check(condition);
//..
}
The above achieves what I need.
My question is: is it possible to do this without casting?