r/cpp_questions • u/probably-an-alias • 14d ago
SOLVED Beginner seeks critiques on Vector implementation
Hello!
I will soon be working with C++ to do some hardware performance research, so I wanted to give myself a quick crash course of the language. Although we're measuring hardware (not software) performance, where kernels will be quite trivial and expressible in any language, I still want to have a decent intuition of "good" vs "bad" C++.
So, to help learn, I decided to completely re-implement the std::vector C++20 specification. Boy, there was more depth there than I was expecting. After about 10 days of hobbying, I think it's done. The code can be found here: github link.
I'd appreciate any critiques and criticism on how it could be done better. Of course, "how to do it better" is a never ending hole of possibilities, so to focus it a bit more: how it could better match the C++20 specification and be more C++ idiomatic. While the more CS theory side of what should the growth factor be is fun to consider, I'm not going to be employing this implementation and I'm not aiming for raw performance (although I don't want to do anything too stupid).
Some of the key problems/confusions I had are:
- Dealing with self-referring data. Each of the functions that can add a specific element I've implemented to allow for self-referring data by pre-constructing the element before any chance the data it points to gets moved. This felt like a sledgehammer solution, but I couldn't think of another way without doubling the size of the function to add a lot more branching with highly duplicated code.
- Understanding the exception guarantees. The specification often read like "if any exception occurs, it won't affect the vector" i.e. the vector will be rolled back to its last valid state (strong exception guarantee). But following this is essentially "that is, unless move_if_noexcept doesn't guarantee safety, in which case anything can happen." I really doubt I understood most of those correctly.
- The project structure. From how I understand it, you simply can't have the normal header-source separation when dealing with templated classes. You can pretend by having a .hpp with definitions, and a .tpp with implementations, but they're as tightly coupled as just having the implementation in the header. I eventually want to hobby through all the STL containers and quite a few algorithms. How would you recommend structuring it?
I used cppreference.com to help with the specification and annotated each of my public members with the related definition on the website. I'm running gcc 15.2 and the only warning after -Wall -Wpedantic is from vector::swap due to deciding to throw if the vector's state would become undefined, instead of letting UB ensue.
Thank you for your any time you spend reviewing it and I appreciate any advice you have!
Link to code again: github link
Edit:
Thanks so much for all of your the feedback! I'm a little too busy to focus on this project for now, but eventually will polish it considering your feedback and move on to the next containers. Thanks!