Unlike some D programmers I don't mind rust but compared to C and C++ the primary difference I'd say is that D has a lot of features that you'd have to emulate with either macros or recursive templates that means that the source files end up much cleaner.
If you want to declare a struct with N members where N is declared at compile time, in C++ it's usually a question of doing a bunch of compile time magic that leaves a roadside picnic of SFINAE everywhere whereas in D it's just a "static foreach" loop inside a template.
Running functions alone is not that interesting, and neither really is generating code. You can do those (arguably better for some cases) with helper programs as a separate build step. But reflection is non-trivial to do externally, so that's the biggest value add, and using it with all three pieces let you close the loop.
But what I’ve mentioned is also very related to the ergonomics of compile-time metaprogramming, since these techniques are all useless if it severely increases builds times up to the point that developers have to use it sparingly. Only Nim and Jai has fully gone the route of using a bytecode VM for compile-time evaluation, while D had a similar project back in 2017 that was abandoned, and for other languages (C++, Zig, etc.) it’s still in the planning stage.