Rust for C++

Trait objects

Rust
trait Foo {
    fn method(&self) -> String;
}

impl Foo for String {
    fn method(&self) -> String { format!("string: {}", *self) }
}

fn main() {
    let a: String = "foo".to_string();

    let b: &Foo = &a;

    b.method();
}
Compiled
pub struct TraitObject {
    pub data: *mut (),
    pub vtable: *mut (),
}

struct FooVtable {
    destructor: fn(*mut ()),
    size: usize,
    align: usize,
    method: fn(*const ()) -> String,
}

fn call_method_on_String(x: *const ()) -> String {
    // the compiler guarantees that this function is only called
    // with `x` pointing to a String
    let string: &String = unsafe { &*(x as *const String) };

    string.method()
}

static Foo_for_String_vtable: FooVtable = FooVtable {
    destructor: /* compiler magic */,
    // values for a 64-bit computer, halve them for 32-bit ones
    size: 24,
    align: 8,

    method: call_method_on_String as fn(*const ()) -> String,
};

fn main() {
    let a: String = "foo".to_string();

    // let b: &Foo = &a;
    let b = TraitObject {
        // store the data
        data: &a,
        // store the methods
        vtable: &Foo_for_String_vtable
    };

    // b.method();
    (b.vtable.method)(b.data);
}