My C++ framework has Buttons. A Button derives from Control. So a function accepting a Control can take a Button as its argument. So far so good.
I also have List<
T>. However, List<
Button> doesn't derive from List<
Control>, which means a function accepting a list of Controls can't take a list of Buttons as its argument. This is unfortunate.
Maybe this is a stupid question, but I don't see how can I solve this :( List<
Button>
should derive from List<
Control>
, but I don't see a way to make this happen "automatically".
Inherited Member Functions of Class Templates are not Available.
Inheritance provides runtime abstraction. Templates are code generation tools. Because the concepts are orthogonal, they may happily be used together to work towards a common goal.
Template inheritance allows you to build a base “skeleton” template that contains all the common elements of your site and defines blocks that child templates can override. Sounds complicated but is very basic. It's easiest to understand it by starting with an example.
Inheritance in C++ Inheritance is a feature or a process in which, new classes are created from the existing classes. The new class created is called “derived class” or “child class” and the existing class is known as the “base class” or “parent class”. The derived class now is said to be inherited from the base class.
Stroustrup has an item on this in his FAQ:
Why can't I assign a vector<Apple*>
to a vector<Fruit*>
You can solve it in two ways:
Control
. Then accept List<Control*>
List<Button>
and List<Control>
then, but it's more boilerplate code, and not necassary most of the time.Here is code for the second alternative. The first alternative is already explained by other answers:
class MyWindow {
template<typename T>
void doSomething(List<T> & l) {
// do something with the list...
if(boost::is_same<Control, T>::value) {
// special casing Control
} else if(boost::is_same<Button, T>::value) {
// special casing Button
}
}
};
To restrict doSomething
only for List<derived from Control>
, some more code is needed (look for enable_if
if you want to know).
Note that this kind of code (looking what type you have) is rather to avoid. You should handle such things with virtual functions. Add a function doSomething
to Control, and override it in Button.
I hate to tell you but if you're using a list of instances to Control instead of pointers to Control, your buttons will be garbage anyway (Google "object slicing"). If they're lists of pointers, then either make the list<button*>
into list<control*>
as others have suggested, or do a copy to a new list<control*>
from the list<button*>
and pass that into the function instead. Or rewrite the function as a template.
So if you previously had a function called doSomething that took a list of controls as an argument, you'd rewrite it as:
template <class TControl>
void doSomething( const std::list<TControl*>& myControls ) {
... whatever the function is currently doing ...
}
void doSomethingElse() {
std::list<Button*> buttons;
std::list<Control*> controls;
doSomething( buttons );
doSomething( controls );
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With