Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Interface vs Template

I have 2 solutions for the same problem - to make some kind of callbacks from one "controller" to the used object and I don't know what to chose.

Solution 1: Use interfaces

struct AInterface {     virtual void f() = 0; };  struct A : public AInterface {     void f(){std::cout<<"A::f()"<<std::endl;} };  struct UseAInterface {     UseAInterface(AInterface* a) : _a(a){}     void f(){_a->f();}      AInterface* _a; }; 

Solution 2: Use templates

struct A {     void f(){std::cout<<"A::f()"<<std::endl;} };  template<class T> struct UseA {     UseA(T* a) : _a(a){}     void f(){_a->f();}      T* _a; }; 

This is just a simple sample to illustrate my problem. In real world the interface will have several functions and one class may(and will!) implement multiple interfaces.

The code will not be used as a library for external projects and I don't have to hide the template implementation - I say this because first case will be better if I need to hide "controller" implementation.

Can you please tell me the advantages/disadvantages for each case and what is better to use?

like image 805
Mircea Ispas Avatar asked May 16 '13 11:05

Mircea Ispas


People also ask

What is the use of template in C?

Templates in c++ is defined as a blueprint or formula for creating a generic class or a function. To simply put, you can create a single function or single class to work with different data types using templates. C++ template is also known as generic functions or classes which is a very powerful feature in C++.

Can you template in C?

C does not have static templates, but you can use macros to emulate them.

Are templates and generics the same?

Comparing Templates and GenericsGenerics are generic until the types are substituted for them at runtime. Templates are specialized at compile time so they are not still parameterized types at runtime. The common language runtime specifically supports generics in MSIL.

What is the advantage of template in C++?

Advantages. C++ templates enable you to define a family of functions or classes that can operate on different types of information. Use templates in situations that result in duplication of the same code for multiple types.


2 Answers

In my opinion performance should be ignored (not really, but micro optimizations should) until you have a reason for that. Without some hard requirements (this is in a tight loop that takes most of the CPU, the actual implementations of the interface member functions is very small...) it would be very hard if not impossible to notice the difference.

So I would focus on a higher design level. Does it make sense that all types used in UseA share a common base? Are they really related? Is there a clear is-a relationship between the types? Then the OO approach might work. Are they unrelated? That is, do they share some traits but there is no direct is-a relationship that you can model? Go for the template approach.

The main advantage of the template is that you can use types that don't conform to a particular and exact inheritance hierarchy. For example, you can store anything in a vector that is copy-constructible (move-constructible in C++11), but an int and a Car are not really related in any ways. This way, you reduce the coupling between the different types used with your UseA type.

One of the disadvantages of templates is that each template instantiation is a different type that is unrelated to the rest of the template instantiations generated out of the same base template. This means that you cannot store UseA<A> and UseA<B> inside the same container, there will be code-bloat (UseA<int>::foo and UseA<double>::foo both are generated in the binary), longer compile times (even without considering the extra functions, two translation units that use UseA<int>::foo will both generate the same function, and the linker will have to discard one of them).

Regarding the performance that other answers claim, they are somehow right, but most miss the important points. The main advantage of choosing templates over dynamic dispatch is not the extra overhead of the dynamic dispatch, but the fact that small functions can be inlined by the compiler (if the function definition itself is visible).

If the functions are not inlined, unless the function takes just very few cycles to execute, the overall cost of the function will trump the extra cost of dynamic dispatch (i.e. the extra indirection in the call and the possible offset of the this pointer in the case of multiple/virtual inheritance). If the functions do some actual work, and/or they cannot be inlined they will have the same performance.

Even in the few cases where the difference in performance of one approach from the other could be measurable (say that the functions only take two cycles, and that dispatch thus doubles the cost of each function) if this code is part of the 80% of the code that takes less than 20% of the cpu time, and say that this particular piece of code takes 1% of the cpu (which is a huge amount if you consider the premise that for performance to be noticeable the function itself must take just one or two cycles!) then you are talking about 30 seconds out of 1 hour program run. Checking the premise again, on a 2GHz cpu, 1% of the time means that the function would have to be called over 10 million times per second.

All of the above is hand waving, and it is falling on the opposite direction as the other answers (i.e. there are some imprecisions could make it seem as if the difference is smaller than it really is, but reality is closer to this than it is to the general answer dynamic dispatch will make your code slower.

like image 131
David Rodríguez - dribeas Avatar answered Sep 22 '22 14:09

David Rodríguez - dribeas


There are pros and cons to each. From the C++ Programming Language:

  1. Prefer a template over derived classes when run-time efficiency is at a premium.
  2. Prefer derived classes over a template if adding new variants without recompilation is important.
  3. Prefer a template over derived classes when no common base can be defined.
  4. Prefer a template over derived classes when built-in types and structures with compatibility constraints are important.

However, templates have their drawbacks

  1. Code that use OO interfaces can be hidden in .cpp/.CC files, whenever templates force to expose the whole code in the header file;
  2. Templates will cause code bloat;
  3. OO interfaces are explicit, whenever requirements to template parameters are implicit and exist only in developer's head;
  4. Heavy usage of templates hurts compilation speed.

Which to use depends on your situation and somewhat on you preferences. Templated code can produce some obtuse compilation errors which has lead to tools such as STL Error decrypt. Hopefully, concepts will be implemented soon.

like image 28
Steve Avatar answered Sep 19 '22 14:09

Steve