4 ms·
C++ templates are bad because they are untyped generics (e.g. C++ doesn't check that the key type for an hashmap is hashable, and instead you get a bunch of err
by devit 9y ago
C++ templates are bad because they are untyped generics (e.g. C++ doesn't check that the key type for an hashmap is hashable, and instead you get a bunch of errors that there is no "hash" overload accepting certain arguments when you try to call a method on the hashmap).
C++ tried to add a type system for templates with "concepts" but it was scrapped.
Rust instead has properly typed generics instead using the trait system, resulting in proper static checking and proper error messages (although without higher kinded types and const generics currently, that C++ instead supports).
Rust also has a powerful macro system, which is unrelated to templates, although you can use them to have kinds of abstractions that the language doesn't support directly (like higher kinded types, const generic or abstracting over mutability), at the cost of having to explicitly perform instantiation, not having inference and having a higher cognitive burder.
- steveklabnik 9y ago> C++ tried to add a type system for templates with "concepts" but it was scrapped. concepts was merged into the C++2020 draft recently, so not entirely scrapped! I forget if it was full-blown concepts or "concepts lite" though.
- pjmlp 9y agoConcepts are on track for C++20 and they are already available on gcc to play with. Besides that, it is already possible to use typed templates in C++, at least with any C++14 compiler and even better on C++17, even if it requires a bit more of effort for the implementer of the generic code. Basically by making use of type traits, static asserts, constexpr if and enable_if. Yes, it isn't as clean as Rust but as shown by Andrei Alexandrescu with D, it opens the door for very powerful designs.
- ogoffart 9y agoBut the C++20 concepts is only concept lite. It does not check the implementation of the template function that it only uses operations available for the conceps. suppose you have a concept Hashable that is only enabled for type with a hash() function. But you can still in the code of your HashMap do a comparison with the < operator, which the Hashable concept don't ensure. In that case you woud only have an error at instentiation type for Hashable types that don't have '<' In Rust, the compiler make sure that your generic function only use operations that exits in the traits declared in the function signature.
- earenndil 9y ago> C++ doesn't check that the key type for an hashmap is hashable I thought it was possible to do something like this? (disclaimer: I don't use c++) class Hashable { abstract char *hash() = 0; } template<typename T: Hashable, typename U> class Hashmap { vector<U> buckets; // etc. }
- kazinator 9y ago> instead you get a bunch of errors that there is no "hash" overload Since you get some kind of compile-time diagnostic, then effectively, the type is checked. Just, within static time, not as early as you'd like, with not as a relevant a diagnostic. ISO C++ doesn't dictate the wording of diagnostics; a C++ implementation could work backward from that error, or do whatever else, in order to phrase the diagnostic in terms of a problem in the template.
- TheCoelacanth 9y agoC++ templates are only typechecked for types that are actually instantiated. Rust generics are typechecked using the traits that the generic is declared with. That's a pretty big difference for people writing generic/templated functions though not as big of a difference for people using them.
- deleted 9y ago[deleted]
- kazinator 9y agoSure, also, C++ code is also typechecked only for files that you feed to the compiler and include in your image. C++ templates being checked only for instantiated types makes them flexible. E.g. a template that accesses type::foo or instance.foo will work with anything that has a member named foo. That template argument doesn't have to have a declared relationship to any type which has foo, which would be an annoying restriction for the users. Types that aren't instantiated don't exist. They don't correspond to anything in the executable image. Worrying about them is like a recording studio fussing over how much reverb to add to a one-handed clap.
- TheCoelacanth 9y agoIt makes them more flexible in the same way that dynamic typing is more flexible. A type error that doesn't execute doesn't really exist either. It's fine to not worry about types that don't get instantiated if you are the only person ever instantiating a template, but that's obviously not always the case. If my template doesn't typecheck for a type that someone else wrote, I don't find out about it until they send me a bug report. With typechecking before instantiating, I find out about it as soon as I write it.