I'm making a base class for my container classes to derive from so I can maintain a consistent interface. It currently looks something like this:
template <typename Datatype>
class BaseClass
{
public:
virtual Datatype Foo() = 0;
virtual Datatype Bar() = 0;
};
template <typename Datatype>
class DerivedClass: public BaseClass<Datatype>
{
public:
virtual Datatype Foo()
{
}
virtual Datatype Bar()
{
}
};
However, with some of my derived classes, Foo()
and Bar()
may need to have different return types from each other. Without having a template parameter for each different return type in the base class, how can I give the derived classes some room for changing this sort of thing?
EDIT:
The types the derived classes use are potentially completely different and invariant. Really, the derived classes aren't guaranteed to have any sort of common ground other than the method names.
It's NOT possible to
return
different data types. The only way would have been to make the methodstemplate
and that is restricted becausevirtual
methods can not be templates.If you know the number of potential types ahead of time you can extend what you've got by adding additional types to the base class template...
This could get out of hand rapidly if you have more than a few types.
Provide a trait which would be specialized in the cases where you need different result.
If the return types are co-variant, they can be changed, or you can write some kind of conversion function and have like, a
real_bar
or something like that.traits may help. The C++ Templates - The Complete Guide book provides an example that illustrates this in the chapter entitled Traits and Policy Classes. It has an example that uses an accumulator to return different types.
EDIT: I can see AProgrammer has given an example already
The above program returned the following:
With
g++
:With Visual Studio 2005
cl.exe
:Though this sample shows how to do it, the answer given by AProgrammer shows a good way of handling it using traits. The above example will work well for fundamental data types but not for user defined types. To handle user defined types, traits is the way to go. Refer to either the "The C++ Template" book by Jossutis or "Modern C++ design" to know more about traits.