My problem when trying to pick up C++ (to write a simple SDL2 game) was that I just couldn't understand the RAII concepts, especially with modern smart pointer classes and STL container classes, and understanding how to use these three features together to be productive. (I just wanted to make a simple grid of cells to port over my simple PICO-8 lemmings-like game.)
Coming from C and thinking of everything in terms of pointers, it was already foreign enough, but the problem was that I couldn't find a definitive reference on how these features interacted and how to use them together successfully. So I gave up on C++. Maybe if I was motivated by needing it for a client project I might have gotten further, who knows.
I suggest you take a serious look at C++ again. It truly is a versatile and powerful language. While it is true that there are a bunch of language features that can be misused, it places the onus squarely on the Designer/Programmer which is how it should be. You can use it as a thin wrapper over C or go as deeply as you like into the OO and Generic programming paradigms. At the same time all abstractions have minimal runtime overhead and pay-as-you-need only.
I was lucky that i discovered C++ early and hence started with it as a "better C". I was not exposed to a lot of upfront complexity (eg. template shenanigans) thus making my learning curve easier. The big mistake people new to C++ make is trying to learn all language features and dark corners. Instead you should look at various aspects of the language separately and understand their applications. That way you learn how to model the problem domain using the appropriate syntactic features of the language. Here are a few different ways of looking at and using the language.
1) As a better C - You can define stricter types, control memory management using techniques like RAII/Smart pointers and enforce better modularization.
2) As an Object-Oriented language - Here you design class hierarchies and provide interfaces, domain libraries and frameworks.
3) As a Generic programming language - Here you define types and learn how to combine them using composition and delegation.
It might be helpful for you to read some of the older C++ books (Modern C++ IMO is more complicated since it mixes the language features in a free manner) to get at the root of "how to think in C++". To that end you might find the following useful;
1) Ruminations on C++ : A Decade of Programming Insight and Experience by Andrew Koenig and Barbara Moo - short chapters explaining various implementation techniques in C++.
2) Scientific and Engineering C++ : An Introduction with Advanced Techniques and Examples by Barton and Nackman - This book will teach you how to design in C++
3) Multi-paradigm design for C++ by James Coplien - Advanced book teaching you how to map problem domain concepts onto language features.
IMO, If you grasp the gist in the above books, you will understand "the heart of C++" and can easily pick up "Modern C++".
The books i had mentioned are old pre-C++11(hence you can easily get cheap used copies) but which give you insight into "how to think and program in C++". They are still relevant, though might not see usage currently, because the language/libraries have evolved.
I am ambivalent on "Modern C++"(they have made it more complicated and invented a new language) and still ramping up on its features and nuances. Haven't really found any insightful book so far (except for "C++ Concurrency in Action" by Anthony Williams which of course is specialized).
However i recently found "Modern C++ Programming Cookbook" by Marius Bancila which seems like a very nice catalog of all the C++11/14/17 features. This seems to go well together with Stroustrup's book.
That's a pretty vague statement though. vector and unique_ptr are class templates (generic classes). To understand them you need at least a basic idea of how that works, which you probably do. After that, you just need to understand their API, which includes copy/move constructors, and destructors, which encompasses RAII. There are tons of blog points explaining RAII.
To be honest, I don't remember exactly what feature it was. Just that I couldn't easily encapsulate a 2d grid of "replaceable" cells. This was like 4-5 months ago and the only documentation we had on C++ at the time was the official Stroustrup book, which was dense.
That sums up my experience. It's hard to find good quality docs, that's up-to-date and not just a beginner's intro that doesn't answer my questions. The only other alternative usually seems to end up being man-pages or other extremely dense and legalesque docs like a ISO standard or something.
Thanks for the sample grid, I've bookmarked it, this'll be helpful for me and my son to understand where we took the wrong road in our implementation.
1. const correctness is awesome. I miss it so much in C# which I happen to code a lot as well. When you have a function which accepts `const Grid<int>& grid`, you can’t call resize() nor change cell values. If you’ll try, the code won’t compile. My given name is Const so I have bias, but still.
2. asserts. They aren’t even C++, these are from C, but IMO they have better ergonomics than C++ exceptions. They compile into nothing in release builds i.e. don’t affect performance, but in debug builds they trap to debugger right away, showing what exactly is not OK. For production code, sometimes it’s a good idea to use preprocessor trickery to turn failed asserts into scary log messages, in release builds.
P.S. It’s possible to implement much better resize(). When neither old nor new size is empty, the version on that gist will essentially turn old data into garbage. A better solution for that case, make a new vector on the stack, write a loop to crop or expand the items (e.g. calling std::copy_n), then call vector::swap to replace Grid::data vector with the newly built one.
Coming from C and thinking of everything in terms of pointers, it was already foreign enough, but the problem was that I couldn't find a definitive reference on how these features interacted and how to use them together successfully. So I gave up on C++. Maybe if I was motivated by needing it for a client project I might have gotten further, who knows.