3 ms·
The difference here is that, C++ templates are closer to just "string replacement", as they're not validated (basic syntax aside) until you instantiate them. As
by aldanor 6y ago
The difference here is that, C++ templates are closer to just "string replacement", as they're not validated (basic syntax aside) until you instantiate them. As such, in C++, your generic type T can be whatever the user decides to stick in there (you can't prevent them doing that), and so you typically have a chance of disabling/enabling certain bits of code by checking various type traits and using hacks like sfinae etc (e.g., "if T is an enum - please use this version of this method; otherwise - substitute this version of the same method", this would be quite typical and idiomatic in C++).
In Rust, generic code is fully validated as it should be, with all trait bounds being matched where need be. So you would rarely end up with needing to figure (at compile time) whether generic type T is an enum or not - because it wouldn't allow you to do anything extra with it out of the box. In Rust, an idiomatic way of adding different behaviours based on the kind of the generic type would be using traits still - e.g., you can have multiple impl blocks on your generic type, each one having different trait bounds on the generic parameter, like - if T: Copy, then implement these extra methods; standard library has tons of examples like this. The only exception that comes to mind is proc macros - when you deal with Rust code in AST form and generate new code at pre-compile-time phase, but that's a completely different story and not really related.
- est31 6y agoOh yeah, C++ templates work more on the token level than Rust generics. Didn't know that type_traits was meant for that. Indeed Rust proc macros, or Rust macros in general, are a better analog to C++ templates than Rust generics. They aren't quite the same, as during evaluation time C++ can do a bit more, and apparently type_traits is an example of what C++ can do statically. Rust's model is different, it wants macro expansion to be done by the time it starts even resolving any non-macro paths, let alone type checking or anything. That being said, you'll be able to emulate something like that once specialization lands (hopefully also included by min_specialization).