C++ hide template idiom from compile-time polymorphism - c++

I'm writing a C++ hardware abstraction layer (HAL), which needs to be as fast as possible.
Polymorphism offers the best API, but Virtual Table lookups really kill the speed of the code.
This lead me to using templates in conjunction with policies to get compile-time polymorphism. But because templates with different arguments get instantiated as completely different types, I can not use them interchangeably in function calls unless the function is a template as well.
However, I dont want to force the user of my HAL library to write all function as templates because I have used templates.
For illustration purposes, suppose this is my HAL:
template<typename T_POLICY>
class I2CManager {
public:
void send(uint8_t data) {
T_POLICY::send(data);
++sent_data;
}
private:
int sent_data; // Just to illustrate that I2CManager has state
};
class I2C1 {
static void send(uint8_t data) { /* Run some code here */ }
};
class I2C2 {
static void send(uint8_t data) { /* Run other code here */ }
};
// OTHER HW
template<typename T_POLICY>
class UARTManager { ··· };
class UART1 { ··· };
class UART2 { ··· };
template<typename T_POLICY>
class TIMERManager { ··· };
class TIMER1A { ··· };
class TIMER1B { ··· };
This works and I can now create a I2CManager with different policies, such as follows. I can even have several I2CManagers running with different policies at the same time.
I2CManager<I2C1> i2c1;
I2CManager<I2C2> i2c2;
i2c1.send(0x11); // This works
i2c2.send(0x11); // This also works
Now, i2c1 and i2c2 have the same public methods, yet they are not interchangeable. Consequently, the user of my HAL library is forced to use templates as well.
// THIS DOES NOT WORK
void foo(I2CManager m) { m.send(0x11); }
foo(my_manager_1);
// BUT THIS WORKS
template<typename T>
void foo(I2CManager<T> m) { m.send(0x11); }
foo(i2c1);
Can I somehow get compile-time polymorphism but allow the end-user to treat it as if it was normal polymorphism? I don't care if the inner code in my library gets ugly or difficult to read for the sake of speed, but the API has to be as simple and intuitive as possible.
Actually, I want foo() to be specialized (and replicated in code) for the different parameters as if it was a template, but I don't want the user of my library to notice it is a template function. Altought alternatives to templates are also welcome.
I don't know if this is even possible, but I have read something about concepts which will appear in the next C++ standard. I want compile-time polymorphism, but as userfrliendly as runtime polymorhism.
Considerations:
Because I'm interfacing HW, each instantiation of my HWManagers with
different policies will be unique (i.e. There is only one
HWManager instance, and one HWManager instance,
and may or may not exist simultaneously).
All instances are created by the library as global variables, and are
not heapable.
All policy methods are extremely short, so having multiple unique
instances due to templates is preferable to Virtual Tables for the
sake of execution speed.
Code size does not matter (its for embedded systems), but RAM usage
and execution speed does. I need as much as possible to be solved
during compile time. Again, I'm willing to have a over-bloated
executable for the sake of avoiding run-time resolutions.
Only up to C++03 supported
Code example edited

All instances are created by the library as global variables, and are not heapable.
You mean something like this, right?
static HWManager<DrierPolicy> drierManager;
static HWManager<FridgePolicy> fridgeManager;
Then, what wrong with letting the user know about them and allow her/him to use those directly like:
drierManager.doStuff();
fridgeManager.doStuff();
And then...
Because I'm interfacing HW, each instantiation of my HWManagers with different policies will be unique
Then why implement the doStuff method as instance ones? Aren't some static methods good enough?
(those are questions, not critiques. Yes, I know, this is hardly an answer - it may be one though - but I needed the extra formatting that the comments do not provide)

Related

When to prefer templated policy based design over non-templated inheritance based design

I am trying to understand the real requirement of the usage of templates for policy based design. Going through the new templated designs in C++ I found that policy based class design is a highly suggested way of design which allows you to 'plug-in' different behaviors from policy classes. A minimal example is the following (a shortened version of the wiki):
template <typename LanguagePolicy>
class HelloWorld : private LanguagePolicy
{
using LanguagePolicy::message;
public:
// Behaviour method
void run() const
{
// policy methods
cout << message();
}
};
class LanguagePolicyA
{
protected:
std::string message() const
{
return "Hello, World!";
}
};
//usage
HelloWorld<LanguagePolicyA> hello_worlda;
hello_worlda.run(); // prints "Hello, World!"
A quick analysis shows that just to get different plugable methods message() we are inheriting from a templated type whose definition can be provided by anyone (and identified at compile time).
But the same level of abstraction (and configurable methods) can be achieved without using a templated code and by the simple old school run time polymorphism as shown below.
class HelloWorld
{
LanguagePolicy *lp; //list of all plugable class
public:
HelloWorld(LanguagePolicy *lpn) {
lp = lpn;
}
// Behaviour method
void run() const
{
// policy methods
cout << lp->message();
}
};
class LanguagePolicy
{
protected:
virtual std::string message() const;
};
class LanguagePolicyA: LanguagePolicy
{
protected:
std::string message() const
{
return "Hello, World!";
}
};
//usage
HelloWorld helloworld(new LanguagePolicyA);
helloworld.run();
Functionality and level of abstraction wise I don't see much of a difference in the two approach (even though the second approach has few extra lines of code for LanguagePolicy, I think it is needed for the other users to know the interface; otherwise understanding LanguagePolicy depends upon the documentation). But I do think the later to be 'clean' (coming from someone who has not used template much). This is because personally in my opinion non-templated classes are cleaner to look at and understand. An extremely good example is the popular library VTK (Visualization Tool Kit) which solves many different problems using the second approach. Even though there are not extensive documentations of VTK, most of us - its users, can just have a look into its class diagrams (sometimes they are quite big) and deduce behaviors of classes; and develop highly configurable and complicated pipelines in our application (can't imaging VTK to be template based :)). The opposite is libraries like STL/BOOST which I don't think is possible for anyone to be able to identify the working of the classes without the use of extensive documentation.
So my question is, is the template based policy design really superior (only in this scenario of policy based design) than virtual inheritance based? If so, when and why?
Both are valid ways of structuring, it actually depends on the requirements. E.g.
Runtime vs compile time polymorphism.
When do you want/can/have to achieve polymorphism ?
Performance overhead of virtual calls
Templates generate code that has no indirections
The actual usage of the class.
When you have to store heterogenous collections, a base class is needed, so you have to use inheritance.
A very good book on policy-based design (a bit dated but good nevertheless) is Modern C++ Design
Depends on the situation I guess... A possible downside of using templates is that the type should be known at compile-time:
HelloWorld<English> hw; // English is plugged at compile-time
In your second example, where you're using a pointer-to-base, this pointer might point to a variety of derived classes. What exactly it points to is not required to be known at compile-time and can therefore be determined by (user-)input at runtime. A possible down-side of this approach is virtual call overhead. In some applications, and on some platforms, this might be unwanted.

C++ Using interfaces or not? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm programming a library and I'm defining an interface for each class by making it's functions and destructor pure virtual. Now, over the time, I've experienced many disadvantages of this design (- just to name some of them: no static methods possible, a lot of virtual inheritence, and, of course, virtual functions are extremly slow.)
The only advantage I see in interfaces is to provide the user with a simple interface and hide the complex details behind them.
But considering all the disadvantages, I don't see why even big, known libraries are using interfaces. (f.e. Ogre 3D, Irrlicht and many other 3D libraries, where performance is the most important thing.)
My question is:
Is there a really convincing point which I'm missing why to use interfaces? Why do others do that? What is more common - using interfaces or
not using them?
Also, when using interfaces - is it valid to make some sort of "hybrid" design? Where classes relying on performance are implemented directly on the interface layer to avoid virtual function calls, and all other classes are implemented as usual? Or is this a bad design?
Your questions
Why use interfaces?
"Interfaces" isn't a well defined term in C++: some people consider any base class with virtual methods to be an interface, while others expect there to be no data members, or no public data members, or no private data members; a few people might say all members must be virtual, and others that they must be pure virtual.
There are pros and cons to each design decision:
base classes with virtual functions are C++'s mechanism for runtime polymorphism, which is a great reason to use them
keeping public data out of the base class preserves freedom to calculate the data on the fly
keeping private data out of the base class avoids having to change it therein when only the implementation changes; such changes force a client recompilation rather than a re-link (being able to just relink is especially useful when the implementation's in a shared object / library that's dynamically linked, as only an updated library need be distributed)
virtual dispatch makes it easy to implement state machines (changing the implementatino at run-time), as well as switching in mock implementations for testing
What is more common - using interfaces or not using them?
That's hugely dependent on the type of application, whether the data inputs or state naturally benefit from runtime polymorphism, and the design decisions made by the programmers' involved. C++ is used for such wildly divergent purposes that no general statement's meaningful.
Also, when using interfaces - is it valid to make some sort of "hybrid" design?
Yes - some "hybrid" approaches are listed under "mitigation" below.
Discussion of your remarks
"virtual functions are extremly slow"
Actual virtual dispatch is necessarily out-of-line, so can be about an order of magnitude worse than an inline call if doing something very simple (e.g. getter/setter for int member), but see mitigation below. (Often the optimiser can avoid virtual dispatch if the dynamic type of the variable involved is known at compile time).
"no static methods possible"
Each class can have static methods - there's just no way to invoke them polymorphically, but what would it even mean to do so? You must have some way to know the dynamic/runtime type as that's the basis for selecting which function to call....
Mitigation
There are a LOT of options for tuning performance - what you should often becomes obvious when you very carefully consider your actual performance problem. The following's a random smattering to give a taste of what's possible and occasionally useful....
Mitigation - granularity of work performed by virtual functions
Try to do as much work as possible per virtual function call. For example, a set_pixel function taking a single pixel would normally be bad interface design. A set_pixels function that can take an arbitrarily long list would be much better, but there're many other alternatives such as providing some kind of virtual drawing surface that the client code can work on without runtime polymorphic dispatch, then pass back the entire surface in one virtual function call.
Mitigation - handover to static-polymorphic code
You can manually orchestrate targeted (per performance profiling results) handover from run-time to compile-time polymorphism (albeit at the cost of manually maintaining a centralised handover routine.
Example
Assume a base class B with virtual void f();, and two derived D1, D2.
First, some polyrmophic algorithmic code that explicitly neuters virtual dispatch:
template <typename T>
struct Algo
{
void operator()(T& t)
{
.. do lots of stuff...
t.T::f(); // each t member access explicitly dispatched statically
...lots more...
}
};
Then, some code to dispatch to a static-type-specific instantiation of a specified algorithm based on dynamic type:
template <template <typename> class F>
void runtime_to_compiletime(B& b) {
if (D1* p = dynamic_cast<D1*>(&b))
F<D1>()(*p);
else if (D2* p = dynamic_cast<D2*>(&b))
F<D2>()(*p);
}
Usage:
D1 d1;
D2 d2;
runtime_to_compiletime<Algo>(d1);
runtime_to_compiletime<Algo>(d2);
Mitigation - orchestrate your own type information
If dynamic_cast is too slow in your implementation, you can get lightning fast switching on dynamic type - at the considerable cost of having to maintain it - as follows:
struct Base
{
Base() : type_(0) { }
int get_type() const { return type_; }
protected:
Base(int type) : type_(type) { }
int type_;
};
struct Derived : Base
{
Derived() : Base(1) { }
};
Then fast switching is trivial:
void f(Base* p)
{
switch (p->get_type())
{
... handle using static type in here ...
}
}
Mitigation - data in "interfaces"
Instead of virtual int f() const; to expose an int data member that only a few derived classes need to calculate on the fly, consider:
class Base
{
public:
Base() : virtual_f_(false) { }
int f() const { return virtual_f_ ? virtual_f() : f_; }
private:
int f_;
bool virtual_f_;
virtual int f() const { }
};
Interfaces are just one of the many mechanisms C++ provides to get reusability and extendibility.
Reuse.
If class A has a pointer to concrete class B, you cannot resuse class A withouth B.
Solution: you introduce an interface I implemented by B, and A has a pointer to I. In this way, you can reuse class A in your software (or in other applications) withouth B (please note that you bring I together with A so you need to implement it someway)
Extendibility.
If a class A has a pointer to concrete class B, class A is bounded to use the "algorithms" provided by B. In future, if you need to use different "algorithms", you are forced to modify A source code.
Solution: if A has a pointer to an interface I, you are free to change I implementation (eg. you can substitute B with C, both implementing I) withouth modifying A source code.
(By the way: mock implementations for testing are included in the extendibility case).
Let's recap:
you don't need to define an interface for each class of your software: you only need to put an interface when you need a hot spot for extendibility or reusability (yes: sadly this require you to think about your design instead of adopt blindly a rule...).
C++ offers many techniques to get the same results: instead of interfaces you can use templates or delegates (see std::function, boost::signal and so on).
the advantage you see in interfaces ("to provide the user with a simple interface and hide the complex details behind them") is best obtained by means of encapsulation. You don't need interface classes to get information hiding. It's enough that your classes don't export details in the public section.
I think you can use next approach: when you have multiply implementations of same interface and implementation selection should be performed at runtime (maybe those interface and implementation wrap some kind of "strategy" etc.) then you should use "interface-implementation" approach (with factory creation, etc.), when it's some kind of utility functionality - than you should avoid "interface-implementation" approach. You also should not forget about correct objects creation/destruction calls between libraries and main code. Hope this helps.
Using non intrusive polymorphism http://isocpp.org/blog/2012/12/value-semantics-and-concepts-based-polymorphism-sean-parent can help with problems of multiple inheritance and virtual inheritance by truly separating interface from implementation. This should eliminate the need for virtual inheritance. In my personal opinion virtual inheritance is a sign of bad/old design.
Also if you are using polymorphism in order to achieve the open closed principal then static polymorphism via CRTP can be much faster.
class Base {
virtual void foo(){
//default foo which the suer can override
}
void bar(){
foo();
}
}
class UserObject : public Base{
void foo() override{
//I needed to change default foo,
//this probably cannot be inlined unless the compiler is really
//good at devirtialization
}
}
becomes
template<typename T_Derived>
class Base {
virtual void foo(){
//default foo which the suer can override
}
void bar(){
static_cast<T_Derived*>(this)->foo();
}
}
class UserObject : public Base<UserObject>{
void foo() {
//I needed to change default foo, ths can be inlined no problem
}
}
One advantage with interfaces is that enables you to write unit tests. When writing a component that uses an interface, you can implement a simple fake version of the interface. The fake version can be given to the component to use during unit tests. This means unit tests will be fast as they don't really execute the library operation. Your fake implementation of the interface can be coded to return values and data to your component to cause it to execute certain code paths and the fake implementation can check that the component made expected calls to the interface.
This convinces me! Obviously, not all libraries are the same. Writing a fake version of a 3D graphics library might not always be useful as you really need to use your own eyes to see the image is correct as a unit test might be tricky to code to check the output is correct here. But, for many other applications unit tests are worth the extra work because they give you confidence to make changes to the code base and be sure it still works as behaves, and help ensure quality.

Static CRTP class without knowing derived type?

Given the following, working code.
#include <iostream>
template<class Detail>
class AbstractLogger
{
public:
static void log(const char* str) {
Detail::log_detailled(str);
}
};
class Logger : public AbstractLogger<Logger>
{
public:
static void log_detailled(const char* str) {
std::cerr << str << std::endl;
}
};
int main(void)
{
AbstractLogger<Logger>::log("main function running!");
return 0;
}
Now, I want to put AbstractLogger into a library, and let the library user define his own logger, like the Logger class here. This has one drawback: AbstractLogger<Logger> can not be used inside the library, since the library can not know Logger.
Notes:
Please no virtual functions or questions why not. Also, I am aware of the similar problem that "static virtual" members are invalid. Maybe, there is a workaround in CRTP :)
C++11 will be interesting, however, I need "usual" C++.
If what you mean is that you want to have a library that uses this as a logging mechanism without knowing the exact instantiating type, I would advice against it.
The only way of doing it while meeting your other requirements (i.e. no virtual functions) is that all your functions/types in the library that need to log are converted into templates that take the Logger type. The net result is that most of your interface becomes a template (although you can probably move a good amount of the implementation to non-templated code, it will make your life much harder than needed, and it will still generate a much larger binary).
If your concern with virtual functions is performance, then you should reconsider your approach and the problems it brings. In particular, logging is expensive. Most logging libraries tackle it by optimizing the non-logging case (by means of macros that avoid calling the logger if the log level/group/... are not enabled), but still leave dynamic dispatch for the actual writting. The cost of the dynamic dispatch is negligible compared with the cost of writing to the console, or a file, or even with the cost of generating the message that will be logged (I am assuming that you not only log literal strings)
The usual approach is to code against a concept, while providing helpers so that users may easily produce types that satisfy one or more of those concepts. As an example, something like boost::iterator_facade is a CRTP helper that makes it easier for a user to write an iterator. Then, that iterator can be used anywhere an iterator is accepted -- for instance in the range constructor of std::vector. Notice how that particular constructor has no foreknowledge of the user-defined type.
In your case, AbstractLogger would be the CRTP helper. The missing piece would be to define e.g. a logger concept. As a result, notice that everything that needs a logger either needs to be implemented as a template or you need a type-erasing container to hold arbitrary loggers.
Concept checks (like those provided by Boost) are convenient for this kind of programming, since they allow to represent a concept with actual code.
Template classes can't be 'put in a library' since they are instantiated by the compiler as specializations of their template parameters.
You may put parameter independent stuff used in the template implementation into a library though.

Designing a C++ library

I am in the process of designing a C++ static library.
I want to make the classes generic/configuarable so that they can support a number of data types(and I don't want to write any data type specific code in my library).
So I have templatized the classes.
But since the C++ "export" template feature is not supported by the compiler I am currently using, I am forced to provide the implementation of the classes in the header file.
I dont want to expose the implementation details of my Classes to the client code which is going to use my library.
Can you please provide me with some design alternatives to the above problem??
Prior to templates, type-agnostic C++ code had to be written using runtime polymorphism. But with templates as well, you can combine the two techniques.
For example, suppose you wanted to store values of any type, for later retrieval. Without templates, you'd have to do this:
struct PrintableThing
{
// declare abstract operations needed on the type
virtual void print(std::ostream &os) = 0;
// polymorphic base class needs virtual destructor
virtual ~PrintableThing() {}
};
class PrintableContainer
{
PrintableThing *printableThing;
public:
// various other secret stuff
void store(PrintableThing *p);
};
The user of this library would have to write their own derived version of PrintableThing by hand to wrap around their own data and implement the print function on it.
But you can wrap a template-based layer around such a system:
template <T>
struct PrintableType : PrintableThing
{
T instance;
virtual void print(std::ostream &os)
{ os << instance; }
PrintableType(const T &i)
: instance(i) {}
};
And also add a method in the header of the library, in the declaration of the PrintableContainer class:
template <class T>
void store(const T &p)
{
store(new PrintableType(p));
}
This acts as the bridge between templates and runtime polymorphism, compile-time binding to the << operator to implement print, and to the copy-constructor also (and of course also forwarding to the nested instance's destructor).
In this way, you can write a library entirely based on runtime polymorphism, with the implementation capable of being hidden away in the source of the library, but with a little bit of template "sugar" added to make it convenient to use.
Whether this is worth the trouble will depend on your needs. It has a purely technical benefit in that runtime polymorphism is sometimes exactly what you need, in itself. On the downside, you will undoubtedly reduce the compiler's ability to inline effectively. On the upside, your compile times and binary code bloat may go down.
Examples are std::tr1::function and boost::any, which have a very clean, modern C++ template-based front end but work behind the scenes as runtime polymorphic containers.
I've got some news for you, buddy. Even with export, you'd still have to release all of your template code -- export just makes it that you don't have to put the definitions in a header file. You're totally stuck. The only technique you can use is split off some functions that are non-templates and put them into a different class. But that's ugly, and usually involves void* and placement new and delete. That's just the nature of the beast.
You can try to obfuscate your code - but you have little choice in C++03 asides from including template code in header files.
Vandevoorde does describe another technique in his book: Explicit instantiation - but that entails having to explicitly instantiate all possible useful combinations.
But for the most comprehensive review of this topic read chapter 6 from C++ Templates: The Complete Guide.
Edit (in response to your comment): You have two options for writing generic code without using templates:
1) Preprocessor - still requires header files
2) using void* - yuk - incredibly unsafe
So no, i do not recommend not using templates for solving problems that templates were specifically designed (albeit somewhat flawed) for.
One problem with templates is that they require compiled code. You never know how the end-user will specialize/instantiate your templates, so your dll-file would have to contain all possible template specializations in compiled form. This means that to export pair<X,Y> template you would have to force the compilication of pair<int,float>, pair<int,string>, pair<string,HWND> and so on... to infinity..
I guess more practical solution for you would be to un-template private/hidden code. You can create special internal functions that would only be compiled for single template specialization. In the following example internal_foo-function is never called from MyClass where A is not int.
template<class A>
class MyClass
{
int a;
float b;
A c;
int foo(string param1);
{
((MyClass<int>*)this)->internal_foo(param1);
}
int internal_foo(string param1); // only called on MyClass<int> instances
};
template<>
__declspec(dllexport) int MyClass<int>::internal_foo(string param1)
{
... secret code ...
}
This of course is a hack. When using it you should be extra careful not to use member variable "c", because it's not always integer (even though internal_foo thinks that it is). And you can't even guard yourself with assertions. C++ allows you to shoot yourself in the foot, and gives you no indications about it until it's too late.
PS. I haven't tested this code so it might require some fine tuning. Not sure for example if __declspec(dllimport) is needed in order for compiler to find internal_foo function from dll-file...
With templates you cannot avoid shipping the code (unless your code only works with a fixed set of types, in which case you can explicitly instantiate). Where I work we have a library that must work on POD types (CORBA/DDS/HLA data definitions), so at the end we ship templates.
The templates delegate most of the code to non-templated code that is shipped in binary form. In some cases, work must be done directly in the types that were passed to the template, and cannot thus be delegated to non-templated code, so it is not a perfect solution, but it hides enough part of the code to make our CEO happy (the people in charge of the project would gladly provide all the code in templates).
As Neil points in a comment to the question, in the vast majority of cases there is nothing magical in the code that could not be rewritten by others.

Template or abstract base class?

If I want to make a class adaptable, and make it possible to select different algorithms from the outside -- what is the best implementation in C++?
I see mainly two possibilities:
Use an abstract base class and pass concrete object in
Use a template
Here is a little example, implemented in the various versions:
Version 1: Abstract base class
class Brake {
public: virtual void stopCar() = 0;
};
class BrakeWithABS : public Brake {
public: void stopCar() { ... }
};
class Car {
Brake* _brake;
public:
Car(Brake* brake) : _brake(brake) { brake->stopCar(); }
};
Version 2a: Template
template<class Brake>
class Car {
Brake brake;
public:
Car(){ brake.stopCar(); }
};
Version 2b: Template and private inheritance
template<class Brake>
class Car : private Brake {
using Brake::stopCar;
public:
Car(){ stopCar(); }
};
Coming from Java, I am naturally inclined to always use version 1, but the templates versions seem to be preferred often, e.g. in STL code? If that's true, is it just because of memory efficiency etc (no inheritance, no virtual function calls)?
I realize there is not a big difference between version 2a and 2b, see C++ FAQ.
Can you comment on these possibilities?
This depends on your goals. You can use version 1 if you
Intend to replace brakes of a car (at runtime)
Intend to pass Car around to non-template functions
I would generally prefer version 1 using the runtime polymorphism, because it is still flexible and allows you to have the Car still have the same type: Car<Opel> is another type than Car<Nissan>. If your goals are great performance while using the brakes frequently, i recommend you to use the templated approach. By the way, this is called policy based design. You provide a brake policy. Example because you said you programmed in Java, possibly you are not yet too experienced with C++. One way of doing it:
template<typename Accelerator, typename Brakes>
class Car {
Accelerator accelerator;
Brakes brakes;
public:
void brake() {
brakes.brake();
}
}
If you have lots of policies you can group them together into their own struct, and pass that one, for example as a SpeedConfiguration collecting Accelerator, Brakes and some more. In my projects i try to keep a good deal of code template-free, allowing them to be compiled once into their own object files, without needing their code in headers, but still allowing polymorphism (via virtual functions). For example, you might want to keep common data and functions that non-template code will probably call on many occasions in a base-class:
class VehicleBase {
protected:
std::string model;
std::string manufacturer;
// ...
public:
~VehicleBase() { }
virtual bool checkHealth() = 0;
};
template<typename Accelerator, typename Breaks>
class Car : public VehicleBase {
Accelerator accelerator;
Breaks breaks;
// ...
virtual bool checkHealth() { ... }
};
Incidentally, that is also the approach that C++ streams use: std::ios_base contains flags and stuff that do not depend on the char type or traits like openmode, format flags and stuff, while std::basic_ios then is a class template that inherits it. This also reduces code bloat by sharing the code that is common to all instantiations of a class template.
Private Inheritance?
Private inheritance should be avoided in general. It is only very rarely useful and containment is a better idea in most cases. Common case where the opposite is true when size is really crucial (policy based string class, for example): Empty Base Class Optimization can apply when deriving from an empty policy class (just containing functions).
Read Uses and abuses of Inheritance by Herb Sutter.
The rule of thumb is:
1) If the choice of the concrete type is made at compile time, prefer a template. It will be safer (compile time errors vs run time errors) and probably better optimized.
2) If the choice is made at run-time (i.e. as a result of a user's action) there is really no choice - use inheritance and virtual functions.
Other options:
Use the Visitor Pattern (let external code work on your class).
Externalize some part of your class, for example via iterators, that generic iterator-based code can work on them. This works best if your object is a container of other objects.
See also the Strategy Pattern (there are c++ examples inside)
Templates are a way to let a class use a variable of which you don't really care about the type. Inheritance is a way to define what a class is based on its attributes. Its the "is-a" versus "has-a" question.
Most of your question has already been answered, but I wanted to elaborate on this bit:
Coming from Java, I am naturally
inclined to always use version 1, but
the templates versions seem to be
preferred often, e.g. in STL code? If
that's true, is it just because of
memory efficiency etc (no inheritance,
no virtual function calls)?
That's part of it. But another factor is the added type safety. When you treat a BrakeWithABS as a Brake, you lose type information. You no longer know that the object is actually a BrakeWithABS. If it is a template parameter, you have the exact type available, which in some cases may enable the compiler to perform better typechecking. Or it may be useful in ensuring that the correct overload of a function gets called. (if stopCar() passes the Brake object to a second function, which may have a separate overload for BrakeWithABS, that won't be called if you'd used inheritance, and your BrakeWithABS had been cast to a Brake.
Another factor is that it allows more flexibility. Why do all Brake implementations have to inherit from the same base class? Does the base class actually have anything to bring to the table? If I write a class which exposes the expected member functions, isn't that good enough to act as a brake? Often, explicitly using interfaces or abstract base classes constrain your code more than necessary.
(Note, I'm not saying templates should always be the preferred solution. There are other concerns that might affect this, ranging from compilation speed to "what programmers on my team are familiar with" or just "what I prefer". And sometimes, you need runtime polymorphism, in which case the template solution simply isn't possible)
this answer is more or less correct. When you want something parametrized at compile time - you should prefer templates. When you want something parametrized at runtime, you should prefer virtual functions being overridden.
However, using templates does not preclude you from doing both (making the template version more flexible):
struct Brake {
virtual void stopCar() = 0;
};
struct BrakeChooser {
BrakeChooser(Brake *brake) : brake(brake) {}
void stopCar() { brake->stopCar(); }
Brake *brake;
};
template<class Brake>
struct Car
{
Car(Brake brake = Brake()) : brake(brake) {}
void slamTheBrakePedal() { brake.stopCar(); }
Brake brake;
};
// instantiation
Car<BrakeChooser> car(BrakeChooser(new AntiLockBrakes()));
That being said, I would probably NOT use templates for this... But its really just personal taste.
Abstract base class has on overhead of virtual calls but it has an advantage that all derived classes are really base classes. Not so when you use templates – Car<Brake> and Car<BrakeWithABS> are unrelated to each other and you'll have to either dynamic_cast and check for null or have templates for all the code that deals with Car.
Use interface if you suppose to support different Break classes and its hierarchy at once.
Car( new Brake() )
Car( new BrakeABC() )
Car( new CoolBrake() )
And you don't know this information at compile time.
If you know which Break you are going to use 2b is right choice for you to specify different Car classes. Brake in this case will be your car "Strategy" and you can set default one.
I wouldn't use 2a. Instead you can add static methods to Break and call them without instance.
Personally I would allways prefer to use Interfaces over templates because of several reasons:
Templates Compiling&linking errors are sometimes cryptic
It is hard to debug a code that based on templates (at least in visual studio IDE)
Templates can make your binaries bigger.
Templates require you to put all its code in the header file , that makes the template class a bit harder to understand.
Templates are hard to maintained by novice programmers.
I Only use templates when the virtual tables create some kind of overhead.
Ofcourse , this is only my self opinion.