I'd bet that C++ gives you more low level control than Crystal does, though I'm not deeply familiar with Crystal.
Zig and Rust both seem to eat at the space that C++ occupies more than what I've seen out of Crystal, but I have not followed it closely at all, so I could well be wrong there. Crystal feels closer to the Ruby flavor to Nim's Python flavor, and I know syntax doesn't imply low-levelness, but yeah.
Except that with D you can use C++ ecosystem rather seamlessly and still have a GC which enables one to not worry about memory management too much. Everyone likes to bash at D's GC, yet it's one of the huge improvements over C++, it doesn't get in the way and you can also deactivate it. The other huge improvement is the saner language. Zig can also do C interop to a certain extent.
https://dlang.org/spec/cpp_interface.html
https://dlang.org/spec/interfaceToC.html
https://ziglearn.org/chapter-4/
> Crystal feels closer to the Ruby flavor to Nim's Python flavorCrystal is to Ruby like what Nim is o Python, except that it's done right with a real LLVM based compiler instead of compiles-to-C nonsense, although I'd wish they copied more APIs out of Ruby. Ruby also compiles to C if you enable MJIT. I don't understand the need for a brand new language to do that when one could have Python do it (like Nuitka does but through the official compiler). Instead they chose to write something like Vala, except Vala was designed that way with a purpose in mind (to build upon GObject).
No doubt there was something I could have done to coax it into behaving, but in C++ that was unnecessary. RAII and ordinary standard library containers were enough to make it work.
This was a while ago, so perhaps things have improved.