| > I find today's C++ extremely challenging to pick up speed for someone coming from let's say, Java. Smart pointers, pointer/references, rvalue reference, copy/move semantics, (perfect) forwarding, constructors, and how all that interacts with templates. It's just so unwieldy complex. The main difference between Java and C++ in the features you listed boils down to a key difference between Java and C++: object ownership and lifecycle management. Java's "let's just heap allocate the world and let the JVM sort itself out" allows Java developers to be oblivious to the need to actually think about the life cycle of any object at all. That's fine for some uses, and definitely most of Java's uses, but it's also something that prevents Java from even being considered an option in performance-minded applications. It also gets Java developers to develop incomplete mental models of how computers work. For example, a Java developer who does not understand pointers/references is also a Java developer who fails to understand Java's value and reference types. A Java developer who doesn't understand constructors has also more pressing matters to concern himself with. In C++, there's a conscientious effort to ensure developers have full control over the life cycle of each and every single object ever instantiated throughout an app session. Smart pointers were added to provide clear semantics on how heap allocated objects should be owned and shared. Move semantics were added because developers want to transfer ownership of resources instead of having to deep copy objects around. These features are aimed at performance and memory safety in a language that by design allows developers to handle low-level details if they want to. Then there's the backwards compatibility. Perfect forwarding is basically syntactic sugar to get rvalue references to work as expected. > The worst thing is that after it finally compiles I feel I can't be sure if I've followed all the rules and best practices correctly or if it's going to blow up spectacularly and potentially unsafely at runtime. The same goes for any programming language. You mentioned Java. I know people who work at an unicorn whose hiring process consists of putting together a Java web service, and they outright rejects people who present a project that hasn't been onboarded onto PMD or SpotBugs. We're talking about companies who hire experts and enforce code reviews, and they still enforce the use of linters and static code analyzers. |
Basically most of the complexity I mention comes from memory management. It's just a lot of details to know about and keep in your head. It's the price to pay for the flexibility and power.
In Java you need to understand references and object lifecycles or you get memory leaks and slow applications.
Actually, I work on a performance sensitive application and it's written in Java and it's a good choice for it, since the performance comes from algorithmic complexity, mostly from asymptotic complexity. A C++ rewrite wouldn't significantly impact the performance of the application.