I want to start this question by saying that it is paradigm-related and that I am only trying to clarify some concepts. So I have been programming in Python for about 2 years now, dipped my toes into Java but not too much and I want to delve into C++. I've used it before but not for large projects with a lot of design involved.
When I first started explored it I believed that it addressed OOP similarly to Java where everything has to implement an interface. Then I bumped into the concept of templates which I immediately though to be a workaround to provide polymorphic behaviour to primitives(ints, floats) which did not implement it(basically what Python did through duck-typing and no formal interfaces). But I soon discovered that templates were used to provide the same behaviour to non-primitive types.
So my question is: what reason is there to use classic polymorphism over templates, and what is the general approach to this in the C++ community?
EDIT Just found this which pretty much answers the question(static polymorphism really need to wrap my head around this terminology).
At the risk of making sweeping generalizations, templates are mostly used similarly to Generics in Java - they allow you to build a class or function that can be used with many different data types. Take std::list, part of the Standard Template Library. You can make a linked list of integers with std::list<int>, or a list of objects with std::list<MyClass>. Another example is std::thread, which uses templates to take a function (or lambda or functor) and its arguments to run in another thread.
As for choosing between a function f(SomeInterface x) and a function template f(T x), it really depends on context and is somewhat subjective. Some things to take into consideration are:
Function templates and class templates are resolved at compile time, so you may get better performance. However,
C++ compilers historically generate barely-descipherable garbage for template errors. Clang has done some work to improve this, and other compilers are getting better in an effort to match Clang. Things are getting better, but it's still pretty ugly.
Don't be afraid to use traditional polymorphism with interfaces and implementation classes. While templates are used instead of of polymorphism in some cases (see C++'s std::thread which uses templates vs. Java's Thread which uses a Runnable interface), polymorphism is still extremely common in C++ libraries and projects.
In short, feel free to consider using templates, but don't look at them as a replacement for polymorphism. Look at a popular C++ library and you're bound to find plenty of polymorphism. Take OGRE, a popular C++ graphics engine. If you look at its class list, you'll find lots of interfaces (such as WindowEventListener and FrameListener) which the user can derive a class from in order to interact with the library.
Related
I'm new to C++, and I have this question because I try to compare C++ to Java.
In Java, interface tell the developer which function to implement in order to use the Class or function I provide. For example, by specify the param type as Runnable, I tell the developer that the param I accepted need to have a run method, Iterable tells that the object need to have an iterator.
In C++, so far as I learned, I have encounter many cases that in compiling time, the compiler ask for some operator. And sometimes I even don't know how to specify the requirement of the param that others pass in.
To summarize my question, what's the general idea of approach when designing an template that I hope can handle more generic usage?
I know C++ is not an 100% object-orient language, so I'm still trying to get used to it, when shifting from Java.
AFAIK Java interfaces are for runtime polymorphism; in C++ they are plain classes that contain only pure virtual methods. Java needs a separate language entity for them as it supports only single inheritance for classes (which simplifies many corner cases) but allows multiple inheritance of interfaces; as C++ allows full multiple inheritance for classes in general, there's no need for this distinction.
OTOH, in C++ you don't use interfaces nearly as often - especially in the standard library, especially in the container part. Often compile-time polymorphism is used, in the form of templates.
Unfortunately as of today there's no way to express what operations should a type parameter of a template provide; the template-equivalent of interfaces - "concepts" - is being worked on by the C++ standard committee - unfortunately since many years now - and it's not ready yet.
For now you may only spell out your requirements in the documentation. If a type passed to the template doesn't satisfy them, you'll just get a compilation error pointing to the template code that tries to do something the type doesn't support. This leads to quite some confusion and horrible error messages, so you can try to mitigate this by strategically placing static_assert about the provided type checking if it conforms to what you need, thus providing better diagnostics in case of error.
Basis: i have very big parallel Fortran90/MPI program which represent complex physical model. I want to add new functionality to it: for example, i need to organize queue of messages, introduce mergesort somewhere and use hash tables.
Problem: i know how write hash table, create queue and code mergesort by my self, but i don't think it is a good idea to invent a bicycle.
Question: what Fortran guru should do in such situation? Should i build binds to C++ classes from Fortran and realize logic there using STL or you can suggest some Fortran STL-like libraries? Thank you.
There are no templates in Fortran and hence no STL. You can try FLIBS for some generic libraries. It generally uses transfer() tricks to achieve generic programming.
There is a preprocessor which adds some templates to Fortran and comes with some small STL, you can try that too named PyF95++. If you have access to academic papers through some library, you can read about it here.
I would avoid mixing it with C++ in this specific case although it can be done. You must instantiate each case separately and interface it to Fortran using a wrapper (bind(C) and iso_c_binding). Only if you have a very limited number of types you want to use the algorithms for it could be worth it.
You can also try to implement some poor-man's templates using the C-preprocessors in Fortran, For smaller libraries it works, but can become too difficult to maintain or ugly for complex things. As an example you can see my implementation of a linked list https://github.com/LadaF/fortran-list .
Generally, there is no clearly right approach or answer, you always have to choose from more possibilities.
In addition to everything that Vladimir F already mentioned, there is now also the Fortran Template Library (FTL). Much of the FTL is a reimplementation of C++'s STL in Fortran, where the C preprocessor is abused for template instantiation. You have to instatiate your templates manually, but otherwise it should be quite convenient from the end user perspective. The documentation can be found here.
The library is still fairly new and while it comes with a lot of unit tests, it hasn't seen much use in the wild yet. You'll also need a very recent Fortran compiler to use it.
Disclaimer: I am the author of this library.
I don't like C++, I like C, but I found I have to know something about C++ just like STL etc., to do some C-like C++.
What should I know about C++ at least? (language specification, API, libs etc.)
I don't agree with your sentence. People who writes C++ code knowing only C are writing in C with classes, and what they usually do is taking advantage of overloading and class/struct member functions.
This, in my opinion, is a bad style, it doesn't use C++ at is best, and in general there's no point in writing code that way. Using some C++ libraries (like, but not only, STL) doesn't improve the situation. You'll be able to find a C library providing any data structure and algorithm provided by STL.
What you need to write C++ is to change your mind, to learn new programming paradigms. C++ is not C with classes, otherwise you're just using marginal features (like function overloading and member functions - which can be easily simulated in C) exchanging that with many issues (like symbol mangling, slow compilation time etc).
http://www.cprogramming.com/tutorial/c-vs-c++.html
Good read for your question
You should learn Object-oriented programming concepts. It helps you to reuse source code and is easier to do maintenance and fix bugs. Object-oriented programming is very important if you want to develop a large project.
From C++, you should learn:
classes and objects: it helps you to abstract what you want to represent.
inheritance and virtual functions: Object-oriented programming features.
exceptions: it helps you to find and handle errors.
templates: you can write classes and functions for any data type.
stl containers: linked list, binary tree,
You can write c code and it will compile fine on a cpp compiler. Some things like enums and voids are a bit different, but other than that, anything you write in c will compile in cpp too.
I'm interested in compiling a list of c++ features that are not advisable for use in embedded systems (and which may cause people to recommend c over c++). Please try to add why if you know, or add your why to others' answers.
Here's one for a start (the only one I know)
Dynamic polymorphism, don't know why, but someone said it's "costly"
The Joint Strike Fighter Coding Standards here: http://www2.research.att.com/~bs/JSF-AV-rules.pdf are a pretty good overview of how to use C++ for embedded programming.
The ban on Dynamic Polymorphism is a holdover from the 90s, and has no rational basis. It takes no longer to call a virtual function than it does to do a switch and a call. If you are going to avoid virtual function calls, you might as well be using C.
Certain features require run-time support, so if you miss the required support, you should avoid those features. In particular, the following features usually need extra run-time support:
exceptions
RTTI
dynamic memory allocation
virtual inheritance (a bit unsure about this one)
People also usually mention templates, but they are only an advanced macro facility -- so you can freely use them in embedded systems. Still, you might want to avoid them since they can lead to code bloat after compilation.
Your embedded system should come with documentation saying what, if any, run-time support for C++ (and otherwise) is available.
You should choose features depending on your device. It could be sensible for some feature or maybe not. It depends on its architecture. For instance, Google has a reduced version of C++ compiler for Android platform. Simple common rule is to avoid constructions that will result in heavy runtime code.
Excessive template use. Multiple template instantiations with different parameters will result in multiple copies of the same functions in your object code, hence increasing its size, unless your compiler is smart enough to fold identical code (e.g. if template depends on a type T, instantiation with int will in most cases be identical to instantiation with long).
A way to avoid code size increase with templates, you can write an unsafe core version of your code, and have thin type-safe template wrappers.
dynamic_cast can be pretty costly CPU-wise because it needs to scan the class hierarchy and do string comparison of class names [citation needed].
Does anybody know of any libraries that use design patterns that are implemented using compile-time techniques e.g. template metaprogramming? I know that Loki implements a few but I need to find other libraries.
Boost.Spirit is a pretty big one.
It depends on what design pattern you are interested in. There are some like "Active Object" and Dispose that would have a hard time being implemented at compile time.
"interpreter" pattern -> boost.ublas and blitz++ both use "expression templates"
"bridge" pattern -> Every standard container takes an "allocator" argument (most of Loki is bridge patterns as well)
"strategy" pattern -> STL template functions choose the best implementation based on the argument types
The only difference in all of these is that the evaluation of the pattern happens when the compiler runs, rather then when the executable runs. So all you need is to adjust your thinking slightly: The templates are the program, and the "C++ compiler" runs and interprets this program. The output of this template program is an object file ready for linking. In other words, your template code's runtime is precisley when your compiler is running. C++ templates are a turing complete functional language, just like lisp or XSLT.
In fact the very first template metaprogram in 1993 had as its output not an executable, but a series of compiler errors that printed the fibonacii sequence or something like that.
Some libraries that use expression templates: ublas, blitz, matrix template Library, ftensor, or Google C++ template matrix to find even more.
by the way, ftensor is really slick http://www.gps.caltech.edu/~walter/FTensor/FTensor.pdf.
I think that you are asking for libraries that help to use design pattern more that libraries using design patterns, isn't it?
There are some in Boost but not too much, like Flyweight - Design pattern to manage large quantities of highly redundant objects.
The not yet released but accepted library Boost.Factory and the rejected library Boost.Singleton
There are also some libraries that implements C++ idioms as Boost.Pimpl (on the review schedule), Scope Exit (accepted), Memoizer.
Doen almal GPG hier?
Any case those implemented in Loki:
- Factory Abstract
- Factory
- Singleton
- Visitor
- Command
In boost Flyweight
In STL you have iterators, and adapters, although I'm pretty sure they don't count
due to being being compile-time?
The original specification is somewhat vague.
Make sure that you do not confuse generic programming (template-based implementations) with other compile-time techniques.
Anyone have a clue as to what the above question means?