Mattias Brändström wrote:
Lets say we have some interfaces declared:
class A { virtual void a() = 0; };
class B { virtual void b() = 0; };
class C { virtual void c() = 0; };
We also have some classes implementing none or some of these
interfaces. Now I think it would be neat if I could define a function
that will accept an object that implemts both interface A and B as
input. Something like this:
void AcceptAAndB(/* parameter type */);
This funtion should accept the following classes:
class AB : public A, public B { };
class ABC : public A, public B, public C { };
The function should not accepts arguments of the following classes:
class JustA : public A { };
class JustB : public B { };
As far as I can see there is no easy way of doing this in C++. But I
would really like to be able to do it. =)
Has anyone around here been trying to do something like this? Any
ideas or thoughts along these lines?
Here is an idea: KISS ['keep it simple, silly']. Accepting interfaces
is pointless unless you use the functions they implement. So, if you
simply define the 'AcceptAAndB' as a template that uses both 'a' and 'b'
functions, you've achieved the goal, as far as C++ is concerned:
template<class Interface> void AcceptAAndB(Interface& ab) {
...
ab.a();
...
ab.b();
}
because a class that doesn't implement both 'a' and 'b' will be rejected
at compile-time. (Of course this presumes 'a' and 'b' are callable,
unlike in your example, where they are private)
Some will argue that there can exist another class
class Implements_a_and_b_not_related_to_A_or_B {
public:
int a();
double b();
};
which the function would happily accept, but this is where you have to
decide whether you need the run-time polymorphism or just compile-time
one.
Another way of doing that is, of course, to introduce a class AB:
class AB : public A, public B {
public:
void a() = 0;
void b() = 0;
};
from which all other classes should derive to be "accepted":
void AcceptAAndB(AB& ab) {
...
}
.. There are probably some template tricks you can play to limit the set
of types a template function can accept. Something like "isBaseOrDerived"
or something in that area. They are neat tricks and demonstrate the power
of C++ generic programming abilities, but I am still to encounter real-
life need for those (not to say that there isn't any).
V