C++ templates are intertwined with parsing and typechecking, while Rust has two separate features that cover the same ground: macros, which are purely parse time, and generics, which are purely run at typechecking time. This has advantages and disadvantages. The advantage of C++'s model is that it has one feature instead of two, and this allows for features like SFINAE that Rust has no analogue to. The advantages of Rust's model are that (1) the implementation is a lot simpler; (2) you can typecheck generics before they're expanded, which is a big improvement in ergonomics; (3) generics cover 90% of the use cases, so you rarely have to reach for macros.
C++ templates also aren't general purpose macros. For example, in Rust you can write a macro that takes an expression `e` and replaces it with `e + 1`.
However, I believe you can't do that with C++ templates. C++ template parameters can be types or primitive values, but not expressions. And the body of a template has to be some sort of declaration, e.g. a function definition or struct definition, but not an expression or statement.
Right, you can write a function that returns its argument plus one, but it couldn't e.g. evaluate `e` more than once (which both C and Rust macros can).