Is there a feature in Rust that makes something like this possible? As far as I know, this is not possible with Rust's generic functions because they work only with data types and not with values.
#include <iostream>
template<int T>
int foo(int a)
{
return -1;
}
template<>
int foo<2>(int a)
{
return a*a;
}
template<>
int foo<3>(int a)
{
return a*a*a;
}
int main()
{
std::cout << "foo<1>(3): "<<foo<1>(3) << std::endl;
std::cout << "foo<2>(3): "<<foo<2>(3) << std::endl;
std::cout << "foo<3>(3): "<<foo<3>(3) << std::endl;
return 1;
}
Result:
foo<1>(3): -1
foo<2>(3): 9
foo<3>(3): 27
The main type of templates that can be implemented in C are static templates. Static templates are created at compile time and do not perform runtime checks on sizes, because they shift that responsibility to the compiler.
Rust has a concept similar to templates called generics. A generics is a struct or trait that takes type parameters just like a template. However but the type can be enforced by saying the traits that it must implement. In addition any errors are meaningful.
There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.
Key differences between generics and C++ templates: Generics are generic until the types are substituted for them at runtime. Templates are specialized at compile time so they are not still parameterized types at runtime. The common language runtime specifically supports generics in MSIL.
TL;DR: Not yet, maybe not ever.
Rust generics are not as powerful, yet, as C++ templates, and may never be.
Specifically here, two features are required:
Note: it is unclear how advanced the specialization will be; in this specific case where you use full specialization it should be enough, however it is not clear whether partial specialization will be implemented, and how.
There are also other missing pieces, though not related to this case:
template <...> using ... = ...;
and allowing to emulate template template parameters,It would be easy to deride Rust developers, or shrug it off as a lack of maturity; it would also be incorrect.
As I mentioned, it is not clear that Rust will ever gain some of those features, not because the developers could not implement them, they certainly could, they certainly could have already, but because there is a strong focus in doing things right1.
For example, specialization is a nightmare in C++. It is Undefined Behavior to instantiate a template with a set of arguments A, and later (or in another translation unit) specialize it in a way that would match A. For functions, this generally manifests as the linker picking either the generic or the specialized version... randomly. It's not fun to debug.
Any modifications to generics has large potential repercussions on the rest of the type system, complex interactions with other language features, and significant changes about what a well-typed program means:
In short, Rust developers are attempting to build a well-principled generics system, and it's not easy.
1There are also concerns about unnecessary complexity, so features are not added "just because", but require motivating use cases which should be compelling enough to justify the additional complexity in the language and the compiler; but that's another gate entirely.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With