Search code examples
templatesgenericsrusttemplate-specialization

Can I do template specialisation with concrete types in rust?


I am a beginner in rust, but used to do C++. One thing that you can do in C++ is template specialisation, e.g.

// A generic sort function
template <class T>
void sort(T arr[], int size)
{
    // code to implement Quick Sort
}
 
// Template Specialization: A function specialized for char data type
template <>
void sort<char>(char arr[], int size)
{
    // code to implement counting sort
}

(see blogpost).

In the above example Quick sort is selected as a default implementation, but counting sort is picked if we want to sort chars.

I played around with Rust, but could not get this to work

fn test<T: std::fmt::Display>(arg: T) {
    println!("T implements Displai trait '{}'", arg)
}

fn test<T>(arg: T) {
    println!("default version called")
}

This gives the name test is defined multiple times.

In Rust, can I create generic functions that pick their implementation based on the type of the argument? If so, can I do this with concrete types, like in C++?

The only similar thing I could find was this post, working with traits, not with concrete types (link here)

Edit

struct Mytype<T> {
    val: T,
}

impl<T> Mytype<T> {
    fn test(&self) {
        println!("any type T")
    }
}
impl Mytype<f64> {
    fn test2(&self) {
        println!("called with f64")
    }
}

fn main() {
    Mytype { val: "" }.test();
    Mytype { val: 1.0 }.test();
    Mytype { val: 1.0 }.test2();
}

In the above example I have a specialised method based on the template type. Here test2 is only available if you use a f64. HOWEVER I still need two different function names, which is not what I want.


Solution

  • No. All forms of specialisations are not currently supported on stable rust. They are, however, planned and in the process of being implemented (tracking issue).

    An extremely limited subset of the planned features are available on nightly using #![feature(min_specialization)].

    As an example, specialising on simple trait bounds is currently rejected and specialising on a specific type is also rejected, even when #![feature(min_specialization)] is in use.

    Note, as a word of caution, don't try and use the #![feature(specialization)] feature if suggested, as it is currently buggy and unsound, with the potential to give undefined behaviour when used.