Heavy use of templates for mobile platforms - c++

I've been flicking through the book Modern C++ Design by Andrei Alexandrescu and it seems interesting stuff. However it makes very extensive use of templates and I would like to find out if this should be avoided if using C++ for mobile platform development (Brew MP, WebOS, iOS etc.) due to size considerations.
In Symbian OS C++ the standard use of templates is discouraged, the Symbian OS itself uses them but using an idiom known as thin templates where the underlying implementation is done in a C style using void* pointers with a thin template layered on top of this to achieve type safety.
The reason they use this idiom as opposed to regular use of templates is specifically to avoid code bloating.
So what are opinions (or facts) on the use of templates when developing applications for mobile platforms.

Go ahead and use templates wherever they make your code easier to understand and to maintain. Avoidance of templates on mobile platforms can be categorized as "premature optimization".
If you run into executable-size issues, then redesign if necessary, but don't start with the assumption that templates will cause problems before you see any actual problems.
A lot of the stuff in "Modern C++ Design" and similar books is not going to lead to bloated code, because so much of it is really designed to ensure type safety and do compile-time metaprogramming magic, rather than to generate code.
Templates can be used to do a lot of different things. They can generate more code than you expect, but that's not a reason to ban their use. It wasn't so long ago that various authorities recommended avoiding exceptions, virtual functions, floating-point math, and even classes due to concerns about code size and performance, but people did those things, and somehow everything worked out fine.

Templates don't necessarily lead to code bloat. If you write a function or class template and instantiate it for a dozen different types then yes, you get a lot of duplicate code generated (probably, anyway. Some compilers can merge identical instantiations back together).
But if a template is instantiated for one type only, then there is zero cost in code size. If you instantiate it a couple of times, you pay a certain cost, but you'd also end up paying if you used any of the other ways to achieve the same thing. Dynamic polymorphism (virtual functions and inheritance) isn't free either. You pay for that in terms of vtables, code generated to facilitate all the type casts and conversions necessary, and simply because of code that can't be inlined or optimized away.
Taking std::vector as an example, then yes, if you use both vector<int> and vector<float>, you get two copies of some of the code. But with templates, only the code that is actually used gets compiled. The member functions that you never call won't generate any code, and even in the functions that are compiled, the compiler may be able to eliminate a lot of code. For example, for certain types, exception handling code may be unnecessary, so the compiler can eliminate it, yielding smaller code than if you'd used dynamic polymorphism, where the compiler would've been unable to make any assumptions about the type being stored. So in this made-up example, you'd get some code generated for both vector<int> and vector<float>, but each of them is going to be a lot smaller than a polymorphic vector as you might find in Java, for example.
The main problem with using templates is that it requires a compiler which supports it. On a PC, that's no problem. On any other platform which has a mature C++ compiler available, it's no problem.
But not all platforms have a modern heavy-duty C++ compiler available. Some don't support a number of advanced features, and some are just not good enough at the optimizations required to make template code work (templates tend to require a lot of inlining, for example). So on some platforms, it may be best to avoid templates. Not because of any concern for code size, but because the compiler may be unable to handle it.

In my personal experience using (and even abusing) templates very rarely result in large code bloat, and compiling with -Os will help a lot.
It's not that common to see huge template classes duplicated (instantiated) many times, both because rarely classes are huge, and because in most cases you only instantiate templates with a few different arguments, not hundreds. Besides it's easy to reuse some common code in your biggest template classes/functions, and compiler will help you in doing this.
Usually size of data (graphics, audio, ...) is orders of magnitude bigger than the code. So I wouldn't worry.
Of course there could be exceptions to what I said, but I guess they'll mostly be about advanced (special / weird / complicated) stuff, not with the most common everyday classes.
Summarizing my suggestion: use templates as much as you want, if something will go wrong you'll find that out by profiling, and you will easily be able to optimize the size.

Whatever you do, do NOT try writing some code, compile it, and compare executable size or code duplication.

I would say that generally (not just related to mobile development) this advice holds. Some of the techniques described in Modern C++ Design can lead to long build times and code bloat.
This is especially true when dealing with "obscure" devices, like cell phones. Many template techniques rely on that the compiler and linker do a perfect job in eliminating unused/duplicate code. If they don't, you risk having hundreds of duplicate std::vector instances scattered all over your code. And trust me, I have seen this happen.
This is not to say Modern C++ Design is a bad book, or that templates are bad. But especially on embedded projects it's best to watch out, because it can bite.

Related

What are the disadvantages of using templates?

Some of the disadvantages would be
its syntax is complex
compiler generates extra code
They are hard to validate. Template code which doesn't get used tends to be seldom compiled at all. Therefore good coverage of test cases is a must. But testing is time-consuming, and then it may turn out the code never needed to be robust in the first place.
Hmm, how about...
3: They can be slow to compile
4: They force things to be calculated at compile time rather than run time (this can also be an advantage, if you prefer fast execution speed over runtime flexibility)
5: Older C++ compilers don't handle them, or don't handle them correctly
6: The error messages that they generate when you don't get the code right can be nearly incomprehensible
Templates expose your implementation to the clients of your code, which makes maintaining your ABI harder if you pass templated objects at library boundaries.
So far no-one seems to have mentioned the main disadvantage I find with templates: code readability plummets!
I'm not referring to syntax issues -- yes the syntax is ugly, but I can forgive that. What I mean is this: I find that with never-seen-before non-templated code, however large the application is, if I start at main() I can usually decode the broad strokes of what a program is doing without problems. And code that merely uses vector<int> or similar doesn't bother me in the slightest. But once code starts to define and use its own templates for purposes beyond simple container types, understandability rapidly goes out the window. And that has very negative implications for code maintenance.
Part of that is unavoidable: templates afford greater expressiveness via the complicated partial-order overload resolution rules (for function templates) and, to a lesser degree, partial specialisation (for class templates). But the rules are so damn complicated that even compiler writers (who I'm happy to acknowledge as being an order of magnitude smarter than I am) are still getting them wrong in corner cases.
The interaction of namespaces, friends, inheritance, overloading, automatic conversions and argument-dependent lookup in C++ is already complicated enough. But when you add templates into the mix, as well as the slight changes to rules for name lookup and automatic conversions that they come with, the complexity can reach proportions that, I would argue, no human can deal with. I just don't trust myself to read and understand code that makes use of all these constructs.
An unrelated difficulty with templates is that debuggers still have difficulty showing the contents of STL containers naturally (as compared to, say, C-style arrays).
The only real disadvantage is that if you make any tiny syntax error in a template (especially one used by other templates) the error messages are not gonna be helpful... expect a couple pages of almost-unusable error msgs;-). Compilers' defect are very compiler-specific, and the syntax, while ugly, is not really "complex". All in all, though -- despite the huge issue with proper error diagnostics -- templates are still the single best thing about C++, the one thing that might well tempt you to use C++ over other languages with inferior implementations of generics, such as Java...
They're complicated for the compiler to parse which means your compilation time will increase. Also it can be hard to parse compiler error messages if you have advanced template constructions.
Less people understand them, epsecially at the level of meta programming, therefore less people can maintain them.
When you use templates, your compiler only generates what you actually use. I don't think there is any disadvantages in using C++ template meta-programming except the compiling time which can be quite long if you used very complex structures as boost or loki libraries do.
A disadvantage: template errors are only detected by the compiler when the template is instantiated. Sometimes, errors in the methods of templates are only detected when the member method is instantiated, regardless if the rest of the template is instantiated.
If I have an error in a method, of a template class, that only one function references, but other code uses the template without that method, the compiler will not generate an error until the erroneous method is instantiated.
The absolute worst: The compiler error messages you get from bad template code.
I have used templates sometimes over the years. They can be handy but from a professional perspective, I am leaning away from them. Two of the reasons are:
1.
The need to either a.) expose the function definitions (not only declarations) "source" code to the "where used" code or b.) create a dummy instantiation in the source file. This is needed for compilation. Option a.) can be done by defining functions in the header or actually including the cpp.
One of the reasons that we tolerate headers in C++ (compared to C# for example) is because of the separation of "interface" from "implementation". Well, templates seem to be inconsistent with this philosophy.
2.
Functions called by a template type parameter instantiation may not be enforced at compile time resulting in link errors. E.g. T example; example.CompilerDoesntKnowIfThisFunctionExistsOnT();
This is "loose" IMHO.
Solutions:
Rather then templates, I lean towards using a base class whereby the derived/container classes know what is available at compile time. The base classes can provide the generic methods and "types" that templates are often used for. This is why source code availability can be helpful if existing code needs to be modified to insert a generic base class in the inheritance hierarchy where needed. Otherwise if, code is closed source, rewrite it better using generic base classes instead of using a template as a work around.
If type is unimportant e.g. vector< T > then how about just using"object". C++ has not provided an "object" keyword and I have proposed to Dr. Bjarne Stroustrup that this would be helpful especially to tell compiler and people reading code that type is not important (for cases when it isn't). I don't that think C++11 has this, perhaps C++14 will?

C++ Meta Templates: A Good or Bad Design Choice?

I'm curious to find out if and when C++ meta templates are a good design choice for systems small to large. I understand that they increase your build time in order to speed up your execution time. However, I've heard that the meta template code is inherently hard to understand by many developers, which could be a problem for a large group of people working on a system with a very large code base (millions of lines of code). Where do you think C++ meta templates are useful (or not)?
Metaprogramming is just another tool in a (C++) programmers' toolbox - it has many great applications, but like anything can be mis- or over- used. I think it's got a bad reputation in terms of 'hard to use', and I think this mainly comes from the fact that it's a significant addition to the language and so takes a while to learn.
As an example of real-world use; I've used template metaprogramming to implement Compile-time asserts and shim libraries in the past; implementing these without templates would either have been impossible or required significantly more code than I had to write.
In the case of the shim library it could have been implemented in a classic object-orientated fashion which could have been designed to have a similar (low) level of code duplication as the templated implementation; however it's runtime performance would have been significantly worse.
If you want to see some good examples of how it can be used, I suggest you read Modern C++ Design by Andrei Alexandrescu (there is a sample chapter on the publisher's website) - IMO this is one of the best books on the subject.
Template metaprogramming doesn't make your code "inherently hard to understand". It moves the complexity around. The underlying metaprogramming code may be a pain to understand, but at the same time, it typically simplifies client code.
If its effect was just to make code harder to read, it wouldn't be used. The reason it is used from time to time is exactly that it simplifies the code as a whole.
Of course, programmers who are not familiar with metaprogramming will have trouble reading or maintaining the code, but isn't that just an argument against working with programmers who don't know their stuff?
Programmers who don't know about a for-loop wil find that hard to read too.
Fairly simple meta-programming is used throughout the standard library, in the form of traits. The standard library seems to be pretty well received, so I think we can say that meta programming is useful there.
I did face a situation where I had to tackle a not-so-big system which heavily used template metaprogramming (specifically static polymorphismus, SFINAE and maybe other techniques). And I can tell you that this will make it harder for the developers. If template metaprogramming is used a lot, every developer must be familiar with the techniques otherwise they won't be able to work productively.
On the other hand, some uses of templates are quite easy to understand and use. For example generic containers (vector), smart pointers, ...
As always, you need to balance the pros and the cons. If performance is your concern (there are other uses for template metaprogramming too), you should first demonstrate that there are significant and important performance gains to be had by using template metaprogramming techniques. (It's even quite possible to make a program that runs slower by hindering the compiler with excessive use of templates, so always measure!)
C++ templates were not originally designed for metaprogramming so even relatively simple problems solved with metaprogramming can produce code that is difficult to understand, especially to people who are not familiar with common template metaprogramming techniques (since they are usually not very intutitive). Also depending on your particular problem you might consider code generation vs. template metaprogramming.
This depends on who you're working with, and what they like and are familiar with. In the absence of any information I'd suggest the following concrete list of uncontroversial (and not very meta...) template 'things' for a new project:
handwritten smart pointers for whatever sorts of things your app uses
STL containers
static assert
And, for advanced users only:
traits used for some obvious standard application (script language bindings and serialization spring to mind)
This is perhaps a bit conservative but it seems to be easy to convince everybody of the value of these things. If well put together, they don't bloat compile times and mostly work pretty well with commonly-found code browsing facilities. And most of the templates shouldn't take much explaining, even to that large subset of C++ programmers who don't really understand templates all that well.
(Regarding boost, and any other template libraries that it has yet to merge with, it seems to be pretty adventurous by the standards of many (most?) C++ programmers at the moment. So it seems to me prudent to avoid it for now.)

What are the good and bad points of C++ templates? [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 3 years ago.
Improve this question
I've been talking with friends and some completely agree that templates in C++ should be used, others disagree entirely.
Some of the good things are:
They are more safe to use (type safety).
They are a good way of doing generalizations for APIs.
What other good things can you tell me about C++ templates?
What bad things can you tell me about C++ templates?
Edit: One of the reasons I'm asking this is that I am studying for an exam and at the moment I am covering the topic of C++ templates. So I am trying to understand a bit more on them.
Templates are a very powerful mechanism which can simplify many things. However to use them properly requires much time and experience - in order to decide when their usage is appropriate.
For me the most important advantages are:
reducing the repetition of code (generic containers, algorithms)
reducing the repetition of code advanced (MPL and Fusion)
static polymorphism (=performance) and other compile time calculations
policy based design (flexibility, reusability, easier changes, etc)
increasing safety at no cost (i.e. dimension analysis via Boost Units, static assertions, concept checks)
functional programming (Phoenix), lazy evaluation, expression templates (we can create Domain-specific embedded languages in C++, we have great Proto library, we have Blitz++)
other less spectacular tools and tricks used in everyday life:
STL and the algorithms (what's the difference between for and for_each)
bind, lambda (or Phoenix) ( write clearer code, simplify things)
Boost Function (makes writing callbacks easier)
tuples (how to genericly hash a tuple? Use Fusion for example...)
TBB (parallel_for and other STL like algorithms and containers)
Can you imagine C++ without templates? Yes I can, in the early times you couldn't use them because of compiler limitations.
Would you write in C++ without templates? No, as I would lose many of the advantages mentioned above.
Downsides:
Compilation time (for example throw in Sprit, Phoenix, MPL and some Fusion and you can go for a coffee)
People who can use and understand templates are not that common (and these people are useful)
People who think that they can use and understand templates are quite common (and these people are dangerous, as they can make a hell out of your code. However most of them after some education/mentoring will join the group mentioned in the previous point)
template export support (lack of)
error messages could be less cryptic (after some learning you can find what you need, but still...)
I highly recommend the following books:
C++ Templates: The Complete Guide by David Vandevoorde and Nicolai Josuttis (thorough introduction to the subject of templates)
Modern C++ Design. Generic Programming and Design Patterns Applied by Andrei Alexandrescu (what is the less known way of using templates to simplify your code, make development easier and result in code robust to changes)
C++ Template Metaprogramming by David Abrahms and Aleksey Gutov (again - different way of using the templates)
More C++ Idioms from Wikibooks presents some nice ideas.
On the positive side, C++ templates:
Allow for generalization of type
Decrease the amount of redundant code you need to type
Help to build type-safe code
Are evaluated at compile-time
Can increase performance (as an alternative to polymorphism)
Help to build very powerful libraries
On the negative side:
Can get complicated quickly if one isn't careful
Most compilers give cryptic error messages
It can be difficult to use/debug highly templated code
Have at least one syntactic quirk ( the >> operator can interfere with templates)
Help make C++ very difficult to parse
All in all, careful consideration should be used as to when to use templates.
My 2c are rather negative.
C++ types were never designed to perform compile time calculations.
The notion of using types to achieve computational goals is very
clearly a hack – and moreover, one that was never sought but rather
stumbled upon
..
The reward for using MP in your code is the moment of satisfaction of
having solved a hard riddle. You did stuff in 100 lines that would
have otherwise taken 200. You grinded your way through
incomprehensible error messages to get to a point where if you needed
to extend the code to a new case, you would know the exact 3-line
template function to overload. Your maintainers, of course, would have
to invest infinitely more to achieve the same.
Good points: powerful; allows you to:
prescribe compile-time attributes and computation
describe generic algorithms and datastructures
do many other things that would otherwise be repetitive, boring, and mistake-prone
does them in-language, without macros (which can be far more hazardous and obscure!)
Bad points: powerful; allows you to:
provoke compile-time errors that are verbose, misleading, and obscure (though not as obscure and misleading as macros...)
create obscure and hazardous misdesigns (though not as readily as macros...)
cause code bloat if you're not careful (just like macros!)
Templates vastly increase the viable design space, which is not necessarily a bad thing, but it does make them that much harder to use well. Template code needs maintainters who understand not just the language features, but the design consequences of the language features; practically speaking, this means many developer groups avoid all but the simplest and most institutionalized applications of C++ templates.
In general, templates make the language much more complicated (and difficult to implement correctly!). Templates were not intentionally designed to be Turing-complete, but they are anyway -- thus, even though they can do just about anything, using them may turn out to be more trouble than it's worth.
Templates should be used sparingly.
"Awful to debug" and "hard to read" aren't great arguments against good template uses with good abstractions.
Better negative arguments would go towards the fact that the STL has a lot of "gotchas", and using templates for purposes the STL already covers is reinventing the wheel. Templates also increase link time, which can be a concern for some projects, and have a lot of idiosyncrasies in their syntax that can be arcane to people.
But the positives with generic code reuse, type traits, reflection, smart pointers, and even metaprograms often outweigh the negatives. The thing you have to be sure of is that templates are always used carefully and sparingly. They're not the best solution in every case, and often not even the second or third best solution.
You need people with enough experience writing them that they can avoid all the pitfalls and have a good radar for when the templates will complicate things more than helping.
One of the disadvantages I haven't seen mentioned yet is the subtle semantic differences between regular classes and instantiations of class templates. I can think of:
typedefed typenames in ancestor types aren't inherited by template classes.
The need to sprinkle typename and template keywords in appropriate places.
Member function templates cannot be virtual.
These things can usually be overcome, but they're a pain.
Some people hate templates (I do) because:
On maintainability pov, the wrong use of templates can have a negative effect ten times stronger than the initial advantage of time they were supposed to bring.
On optimization pov, compiler optimizations they allow are nothing compared to an optimal algorithm and the use of multi threading.
On compiling time pov, wrong use of templates can a very negative effect on parsing, compilation and linking phases, when poorly written templated declaration brings tons of useless parasite declarations in each compilation units (here is how 200 lines of code can produce an .obj of 1Mb).
To me templates are like a chainsaw with an integrated flame thrower that can also launch grenades. One time in my life I may have a specific need of that. But most of the time, I'm using a regular hammer and a simple saw to build things and I'm doing a pretty good job that way.
Advantage: Generic Datatypes can be created.
Disadvantage: Code Bloating
I don't see how they are hard to read. What is unreadable about
vector <string> names;
for example? What would you replace it with?
Reusable code is made with template. Its application is in accordance with the profile of each.

Drawbacks to templates and the STL in C++ [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 9 years ago.
Improve this question
Are there any drawbacks to using the STL or templates. Are there any situations for which they are inappropriate.
First, you should use probably use them if they help you solve your problem. Templates are a very important part of C++ and have been part of the standard for years. STL is very powerful and fast at run time and should be supported on all decent compilers, but of course there are issues.
If you have a really old compiler, STL might not be completely supported.
The thread-safety of the STL implementation might be work for your application
Templates can lead to slower compile-times and possibly larger executable, especially with older compilers.
Compilers often produce incomprehensible error messages on code using templates.
just to name a few, but the drawbacks of not using them are likely to be much greater.
Obvious disadvantages:
The syntax can be horrible - some bits of template syntax in C++ are really pushing the limits of sanity, and overlap with other parts of the language (e.g. >>)
Lots of people don't understand the STL very well, so you might restrict your audience.
Error messages tend to be hideously complicated.
The design of the STL collections tends to lead to a lot of copying of objects. The original 'smart pointer' (std::auto_ptr) wasn't suitable for use in most collections. Things have improved in this regard recently (TR1)
There are several potential benefits and drawbacks
Templates expand the size of the resulting code.
Templated code is expanded and processed at compile time which may make compile times longer. (On the other hand, executable code may be more efficient).
Mis-used STL elements can result in slower code
The STL actually makes code more readable (my opinion differs from Will's). Like any language or library, you have to understand it to use it appropriately... which is a drawback for people who don't know it.
If you are using templates in a meta-programming sense (don't confuse w/ using the STL), the code looks like a language completely different from C++. It can be harder to parse through what the code is actually doing. (OTOH, done right - meta-programming makes you focus on architecture and design; it also brings more of the errors to compile time vs. runtime. This is a big win when you have a critical feature and you can catch an incorrectly coded piece at compile time rather than having a customer catch it during operation!)
Having said that, we use C++ and templates (and in some areas, meta-programming techniques) to the benefit of our overall code base. The code is slightly larger than it might be without templates, but the trade-offs in performance and maintainability outweigh the size. We do have skilled/experienced C++ programmers working on developing and maintaining the code.
If you're using drawbacks to decide whether to use C++ features/libraries or not - make sure you equally weigh the benefits both for the language and what your project/product/company is willing to trade off. Hope this helps.
Edit: One other major drawback I forgot to mention - portability. If you need to write portable code, templates may not be the right way to go. Most popular compilers today support the STL, however most is not all. The meta-programming techniques can be real killers to portability, so that is a definite consideration for deciding appropriateness of its use.
For embedded device programming (in my case -- smartphones). Templates are discouraged because of the concern for generated code size (small amount of RAM and disk space). Also the compilers are pretty ancient and probably can't handle some template related constructs.
Heavy template abuse (in particular
template meta-programming and Boost
addiction) can lead to excessively
long compile and link times.
You also wind up with executables
that have considerably larger
(unstripped) binaries, but generally
that isn't a terrible issue.
Poorly designed templates can also
increase code duplication further
exacerbating the executable size
issue.
For class templates with large
implementations also need to
consider the fact that using a
template for them means moving the
entire class body into a header
somewhere. This places a lot more
load on the linker if the template
is used in multiple places.
Error messages from heavily templated code can be daunting to the uninitiated and are rarely if ever as clear as the error messages you get from untemplated code.
That said, for most applications templates are a wonderful tool for code reuse and help lift the level of discourse from reimplementing to reusing code; rarely do these issues trump the benefits.
To paraphrase Andrei Alexandrescu of Modern C++ Design fame. Template are an orthogonal structure to multiple inheritance. They both have complementary trade-offs and benefits. Templates have rich mechanics but specialization of templates does not scale.
The goal of template is to provide abstraction with minimal performance penalty. In most cases, benefits outweigh drawbacks. Most of the issues with templates are from compiler and debugger support.
My pet peeve about template: it defeats smart build system due to header dependencies. Developing template code tends to cause a lot more recompilation of untouched code than developing a pure OO based system, especially if the latter use the DIP (dependency inversion principle) well. This exacerbates the slow compilation problem. OTOH, faster dev hardware these days make things much more tolerable than before.
As for STL (as well as Boost), their goal is to provide portable and reasonably efficient data structure and algorithms. They're not necessary the best choice for certain performance critical applications. For example: although hash_map (tr1/unordered_map) performs reasonably well for average cases, special purpose hash tables (e.g., the google sparse/dense hash table library) can greatly outperform generic STL implementations in terms of memory usage or speed.
There are a lot of philosophical (at best) arguments for and against C++ templates, but the one that I tend to accept the most is that the mechanism by which they are instantiated at compile time generates a considerable amount of code bloat.
While this isn't typically much of a concern, when you're writing code for an embedded system with very limiting restrictions on binary size it makes a significant impact.
In the MSVC implementation, std::string has an overhead of 26 bytes PER STRING, even if the string is empty. If you were doing just char*, it would be 4 bytes per string.
Complex STL containers (and for that matter any complex C++ class) make debugging much more difficult.
Besides the unreadable error messages mentioned before, there is usually very little support in current debuggers for handling STL constructs. For example, it is much easier to examine a native C array at runtime, than a vector<> container.
Hopefully the situation will change with time.
Other than that, templates are wonderful.
One might be that they translate poorly to other object-oriented languages that don't support templates such as C# and Java, so if you have a developer group coming from those languages, they will face a steeper learning curve.
The way templates get instantiated requires you to be careful about how to declare and define your templates when you share them across translation units. The book "C++ templates: The complete guide" is a good source of information about how to handle this.
Compiler and linker error messages for templates tend to be very, very verbose. You'll have to get used to that, and I think there are some scripts/tools that make them more readable, but I don't have any experience with them.
But apart from that templates are great!
See the templates section of the C++ FQA [sic] for lots of good reasons to not use templates.

What can C++ do that is too hard or messy in any other language?

I still feel C++ offers some things that can't be beaten. It's not my intention to start a flame war here, please, if you have strong opinions about not liking C++ don't vent them here. I'm interested in hearing from C++ gurus about why they stick with it.
I'm particularly interested in aspects of C++ that are little known, or underutilised.
RAII / deterministic finalization. No, garbage collection is not just as good when you're dealing with a scarce, shared resource.
Unfettered access to OS APIs.
I have stayed with C++ as it is still the highest performing general purpose language for applications that need to combine efficiency and complexity. As an example, I write real time surface modelling software for hand-held devices for the surveying industry. Given the limited resources, Java, C#, etc... just don't provide the necessary performance characteristics, whereas lower level languages like C are much slower to develop in given the weaker abstraction characteristics. The range of levels of abstraction available to a C++ developer is huge, at one extreme I can be overloading arithmetic operators such that I can say something like MaterialVolume = DesignSurface - GroundSurface while at the same time running a number of different heaps to manage the memory most efficiently for my app on a specific device. Combine this with a wealth of freely available source for solving pretty much any common problem, and you have one heck of a powerful development language.
Is C++ still the optimal development solution for most problems in most domains? Probably not, though at a pinch it can still be used for most of them. Is it still the best solution for efficient development of high performance applications? IMHO without a doubt.
Shooting oneself in the foot.
No other language offers such a creative array of tools. Pointers, multiple inheritance, templates, operator overloading and a preprocessor.
A wonderfully powerful language that also provides abundant opportunities for foot shooting.
Edit: I apologize if my lame attempt at humor has offended some. I consider C++ to be the most powerful language that I have ever used -- with abilities to code at the assembly language level when desired, and at a high level of abstraction when desired. C++ has been my primary language since the early '90s.
My answer was based on years of experience of shooting myself in the foot. At least C++ allows me to do so elegantly.
Deterministic object destruction leads to some magnificent design patterns. For instance, while RAII is not as general a technique as garbage collection, it leads to some impressive capabilities which you cannot get with GC.
C++ is also unique in that it has a Turing-complete preprocessor. This allows you to prefer (as in the opposite of defer) a lot of code tasks to compile time instead of run time. For instance, in real code you might have an assert() statement to test for a never-happen. The reality is that it will sooner or later happen... and happen at 3:00am when you're on vacation. The C++ preprocessor assert does the same test at compile time. Compile-time asserts fail between 8:00am and 5:00pm while you're sitting in front of the computer watching the code build; run-time asserts fail at 3:00am when you're asleep in Hawai'i. It's pretty easy to see the win there.
In most languages, strategy patterns are done at run-time and throw exceptions in the event of a type mismatch. In C++, strategies can be done at compile-time through the preprocessor facility and can be guaranteed typesafe.
Write inline assembly (MMX, SSE, etc.).
Deterministic object destruction. I.e. real destructors. Makes managing scarce resources easier. Allows for RAII.
Easier access to structured binary data. It's easier to cast a memory region as a struct than to parse it and copy each value into a struct.
Multiple inheritance. Not everything can be done with interfaces. Sometimes you want to inherit actual functionality too.
I think i'm just going to praise C++ for its ability to use templates to catch expressions and execute it lazily when it's needed. For those not knowing what this is about, here is an example.
Template mixins provide reuse that I haven't seen elsewhere. With them you can build up a large object with lots of behaviour as though you had written the whole thing by hand. But all these small aspects of its functionality can be reused, it's particularly great for implementing parts of an interface (or the whole thing), where you are implementing a number of interfaces. The resulting object is lightning-fast because it's all inlined.
Speed may not matter in many cases, but when you're writing component software, and users may combine components in unthought-of complicated ways to do things, the speed of inlining and C++ seems to allow much more complex structures to be created.
Absolute control over the memory layout, alignment, and access when you need it. If you're careful enough you can write some very cache-friendly programs. For multi-processor programs, you can also eliminate a lot of slow downs from cache coherence mechanisms.
(Okay, you can do this in C, assembly, and probably Fortran too. But C++ lets you write the rest of your program at a higher level.)
This will probably not be a popular answer, but I think what sets C++ apart are its compile-time capabilities, e.g. templates and #define. You can do all sorts of text manipulation on your program using these features, much of which has been abandoned in later languages in the name of simplicity. To me that's way more important than any low-level bit fiddling that's supposedly easier or faster in C++.
C#, for instance, doesn't have a real macro facility. You can't #include another file directly into the source, or use #define to manipulate the program as text. Think about any time you had to mechanically type repetitive code and you knew there was a better way. You may even have written a program to generate code for you. Well, the C++ preprocessor automates all of these things.
The "generics" facility in C# is similarly limited compared to C++ templates. C++ lets you apply the dot operator to a template type T blindly, calling (for example) methods that may not exist, and checks-for-correctness are only applied once the template is actually applied to a specific class. When that happens, if all the assumptions you made about T actually hold, then your code will compile. C# doesn't allow this... type "T" basically has to be dealt with as an Object, i.e. using only the lowest common denominator of operations available to everything (assignment, GetHashCode(), Equals()).
C# has done away with the preprocessor, and real generics, in the name of simplicity. Unfortunately, when I use C#, I find myself reaching for substitutes for these C++ constructs, which are inevitably more bloated and layered than the C++ approach. For example, I have seen programmers work around the absence of #include in several bloated ways: dynamically linking to external assemblies, re-defining constants in several locations (one file per project) or selecting constants from a database, etc.
As Ms. Crabapple from The Simpson's once said, this is "pretty lame, Milhouse."
In terms of Computer Science, these compile-time features of C++ enable things like call-by-name parameter passing, which is known to be more powerful than call-by-value and call-by-reference.
Again, this is perhaps not the popular answer- any introductory C++ text will warn you off of #define, for example. But having worked with a wide variety of languages over many years, and having given consideration to the theory behind all of this, I think that many people are giving bad advice. This seems especially to be the case in the diluted sub-field known as "IT."
Passing POD structures across processes with minimum overhead. In other words, it allows us to easily handle blobs of binary data.
C# and Java force you to put your 'main()' function in a class. I find that weird, because it dilutes the meaning of a class.
To me, a class is a category of objects in your problem domain. A program is not such an object. So there should never be a class called 'Program' in your program. This would be equivalent to a mathematical proof using a symbol to notate itself -- the proof -- alongside symbols representing mathematical objects. It'll be just weird and inconsistent.
Fortunately, unlike C# and Java, C++ allows global functions. That lets your main() function to exist outside. Therefore C++ offers a simpler, more consistent and perhaps truer implementation of the the object-oriented idiom. Hence, this is one thing C++ can do, but C# and Java cannot.
I think that operator overloading is a quite nice feature. Of course it can be very much abused (like in Boost lambda).
Tight control over system resources (esp. memory) while offering powerful abstraction mechanisms optionally. The only language I know of that can come close to C++ in this regard is Ada.
C++ provides complete control over memory and as result a makes the the flow of program execution much more predictable.
Not only can you say precisely at what time allocations and deallocations of memory occurs, you can define you own heaps, have multiple heaps for different purposes and say precisely where in memory data is allocated to. This is frequently useful when programming on embedded/real time systems, such as games consoles, cell phones, mp3 players, etc..., which:
have strict upper limits on memory that is easy to reach (constrast with a PC which just gets slower as you run out of physical memory)
frequently have non homogeneous memory layout. You may want to allocate objects of one type in one piece of physical memory, and objects of another type in another piece.
have real time programming constraints. Unexpectedly calling the garbage collector at the wrong time can be disastrous.
AFAIK, C and C++ are the only sensible option for doing this kind of thing.
Well to be quite honest, you can do just about anything if your willing to write enough code.
So to answer your question, no, there is nothing you can't do in another language that C++ can't do. It's just how much patience do you have and are you willing to devote the long sleepless nights to get it to work?
There are things that C++ wrappers make it easy to do (because they can read the header files), like Office development. But again, it's because someone wrote lots of code to "wrap" it for you in an RCW or "Runtime Callable Wrapper"
EDIT: You also realize this is a loaded question.