Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent of specific template usage in C++ for Rust

Tags:

templates

rust

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
like image 890
Darius Duesentrieb Avatar asked Dec 06 '17 13:12

Darius Duesentrieb


People also ask

Can we use template in C?

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.

Are rust generics templates?

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.

How will you restrict the template for a specific datatype?

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.

Are C++ templates the same as generics?

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.


1 Answers

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:

  • RFC 2000: Const generics: which will enable non-type generic parameters,
  • RFC 2000: Specialization on const generics.

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:

  • RFC 1598: Generic Associated Types: equivalent to nested template <...> using ... = ...; and allowing to emulate template template parameters,
  • variadics: there have been multiple RFCs, but none seems to have gain much foothold.

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:

  • they are therefore heavily scrutinized,
  • and there is a strong push toward going slow and building incrementally, so as to evaluate those impacts, interactions and changes one at a time.

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.

like image 157
Matthieu M. Avatar answered Oct 12 '22 09:10

Matthieu M.