It's quite hard to explain what I'm trying to do, I'll try: Imagine a base class A
which contains some variables, and a set of classes deriving from A
which all implement some method bool test()
that operates on the variables inherited from A
.
class A {
protected:
int somevar;
// ...
};
class B : public A {
public:
bool test() {
return (somevar == 42);
}
};
class C : public A {
public:
bool test() {
return (somevar > 23);
}
};
// ... more classes deriving from A
Now I have an instance of class A
and I have set the value of somevar
.
int main(int, char* []) {
A a;
a.somevar = 42;
Now, I need some kind of container that allows me to iterate over the elements i
of this container, calling i::test()
in the context of a
... that is:
std::vector<...> vec;
// push B and C into vec, this is pseudo-code
vec.push_back(&B);
vec.push_back(&C);
bool ret = true;
for(i = vec.begin(); i != vec.end(); ++i) {
// call B::test(), C::test(), setting *this to a
ret &= ( a .* (&(*i)::test) )();
}
return ret;
}
How can I do this? I've tried two methods:
- forcing a cast from B::* to A::*, adapting a pointer to call a method of a type on an object of a different type (works, but seems to be bad);
- using std::bind + the solution above, ugly hack;
- changing the signature of
bool test()
so that it takes an argument of typeconst A&
instead of inheriting from A, I don't really like this solution because somevar must be public.
EDIT:
Solution (1) is:
typedef bool (A::*)() mptr;
std::vector<mptr> vec;
vec.push_back(static_cast<mptr>(&T::test));
std::vector<mptr>::iterator i;
for(i = vec.begin(); i != vec.end(); ++i) {
(a .* (*i))();
}
I'm not sure the static cast is safe.