如何在Rust中复制基于C ++模板的SFINAE模式?

时间:2018-06-09 21:24:00

标签: rust traits sfinae

我有以下内容:

trait Runnable {
    fn run(&self);
}

struct Foo<T> {
    // Something
}

impl<T> Runnable for Foo<T>
where
    T: Send + Sync,
{
    fn run(&self) {}
}

impl<T> Runnable for Foo<T>
where
    T: Send + ?Sync,
{
    fn run(&self) {}
}

编译器抱怨重复impl,即使T在两种情况下都是互斥的:

error[E0119]: conflicting implementations of trait `Runnable` for type `Foo<_>`:
  --> src/main.rs:16:1
   |
9  | / impl<T> Runnable for Foo<T>
10 | | where
11 | |     T: Send + Sync,
12 | | {
13 | |     fn run(&self) {}
14 | | }
   | |_- first implementation here
15 | 
16 | / impl<T> Runnable for Foo<T>
17 | | where
18 | |     T: Send + ?Sync,
19 | | {
20 | |     fn run(&self) {}
21 | | }
   | |_^ conflicting implementation for `Foo<_>`

1 个答案:

答案 0 :(得分:4)

你想要的是专业化:

#![feature(specialization)]

trait Runnable {
    fn run(&self);
}

struct Foo<T> {
    _t: T,
}

impl<T> Runnable for Foo<T>
where
    T: Send + Sync,
{
    fn run(&self) {}
}

impl<T> Runnable for Foo<T>
where
    T: Send,
{
    default fn run(&self) {}
//  ^^^^^^^ this is the magic you need
}

fn main() {}

但是,从Rust 1.26.2开始,专业化并不稳定,需要夜间编译器。