Alex Badics (admin@stickman.hu)
C++
void f1(T &a);
void f2(const T &a);
void f3(T a);
void f3r(T &&a);
/*...*/
T val;
f1(val);
f2(val);
f3(val);
f3r(std::move(val));
Rust
fn f1(a: &mut T);
fn f2(a: &T);
fn f3(a: T);
/*...*/
let val = T::new();
f1(&mut val);
f2(&val);
f3(val.clone());
f3(val);
C++
auto vec = std::vector<int>();
vec.push_back(5);
auto val = vec[0];
Rust
let vec = Vec::<i32>::new();
vec.push(5);
let val = vec[0];
Still Rust
fn int_returner() -> i32 {
let vec = Vec::new();
vec.push(5);
return vec[0];
}
The problem
auto even = std::find_if(
vec1.begin(),
vec2.end(),
is_even
);
C++
template<typename It>
std::vector<int>
squares(It first, It last) {
std::vector<int> result;
result.reserve(
std::distance(first, last)
);
std::transform(
first,
last,
std::back_inserter(result),
[](int i){return i * i;}
);
return result;
}
Rust
pub fn squares<It>(it: It) -> Vec<i32>
where It: Iterator<Item=i32>
{
it.map(|i| i * i).collect()
}
C++23
std::vector<int>
squares(std::ranges::input_range auto&& range) {
return range
| std::views::filter([](int i){ return i % 2 == 0; })
| std::views::transform([](int i){ return i * i; })
| std::ranges::to<std::vector>();
}
C++11
void stuff_sync(std::mutex mtx, Data &data) {
auto prepared = prepare_things();
{
std::unique_lock<std::mutex>(mtx);
stuff(prepared, data);
}
unprepare(prepared);
}
Rust
fn stuff_sync(data: &mut Mutex<Data>) {
let prepared = prepare_things();
{
let locked_data =
data.lock().unwrap();
stuff(&prepared, &*locked_data);
}
unprepare(prepared);
}
C
void add16x(int *to, const int *from) {
*to = *from;
for(int i=0; i<15; ++i) {
*to += *from;
}
}
Rust
fn add16x(to: &mut isize, from: &isize) {
*to = *from;
for i in 0..15 {
*to += *from;
}
}
C
void add16x(int *to, const int *from) {
*to = *from;
for(int i=0; i<15; ++i) {
*to += *from;
}
}
int add_test() {
int a = 1;
add16x(&a, &a);
return a;
}
Rust
fn add16x(to: &mut isize, from: &isize) {
*to = *from;
for i in 0..15 {
*to += *from;
}
}
fn add_test() -> isize{
let a = 1;
add16x(&mut a, &a);
return a;
}
C
void add16x(int *to, const int *from) {
*to = *from;
for(int i=0; i<15; ++i) {
*to += *from;
}
}
add16x:
mov eax, dword ptr [rsi]
add eax, eax
mov dword ptr [rdi], eax
add eax, dword ptr [rsi]
# ....
mov dword ptr [rdi], eax
add eax, dword ptr [rsi]
mov dword ptr [rdi], eax
ret
Rust
fn add16x(to: &mut isize, from: &isize) {
*to = *from;
for i in 0..15 {
*to += *from;
}
}
mov eax, dword ptr [rsi]
shl eax, 4
mov dword ptr [rdi], eax
ret
restrict
void add16x(int *restrict to, const int *from) {
*to = *from;
for(int i=0; i<15; ++i) {
*to += *from;
}
}
mov eax, dword ptr [rsi]
shl eax, 4
mov dword ptr [rdi], eax
ret
C++
struct BaseA {
virtual ~BaseA(){};
virtual void do_stuff() = 0;
virtual void undo_stuff() = 0;
};
struct BaseB {
virtual ~BaseB(){};
virtual void thing() = 0;
};
struct Derived: BaseA, BaseB {
void do_stuff() override{/* */}
void undo_stuff() override {/* */}
void thing() override {/* */}
}
Rust
pub trait BaseA{
fn do_stuff(&mut self);
fn undo_stuff(&mut self);
}
pub trait BaseB{
fn thing(&mut self);
}
pub struct Derived {
/* ... */
}
impl BaseA for Derived {
fn do_stuff(&mut self) {/**/}
fn undo_stuff(&mut self) {/**/}
}
impl BaseB for Derived {
fn thing(&mut self) {/**/}
}
C++
void dyn_param(BaseB& o) {
o.thing();
}
void tpl_param(std::derived_from<BaseB> auto &o) {
o.thing();
}
void caller() {
Derived d;
dyn_param(d);
tpl_param(d);
}
Rust
pub fn dyn_param(o: &mut dyn BaseB) {
o.thing();
}
pub fn tpl_param(o: &mut impl BaseB) {
o.thing();
}
pub fn caller() {
let mut d = Derived{/**/};
dyn_param(&mut d);
tpl_param(&mut d);
}
C++
Derived derived;
BaseA &base_a=derived;
BaseB &base_b=derived;
Rust
let derived = Derived{/**/};
let base_a: &BaseA = &derived;
let base_b: &BaseB = &derived;
C++
void fn1(unsigned a);
void fn2(unsigned a);
void fn_ptrs() {
auto fp = fn1;
fp = fn2;
fp(5);
}
Rust
fn fn1(a: usize){}
fn fn2(a: usize){}
fn fn_ptrs(){
let mut fp = fn1;
fp = fn2;
fp(5);
}
error[E0308]: mismatched types
--< >source<:6:10
|
5 | let mut fp = fn1;
| --- expected due to this value
6 | fp = fn2;
| ^^^ expected fn item, found a different fn item
|
= note: expected fn item `fn(_) {fn1}`
found fn item `fn(_) {fn2}`
= note: different fn items have unique types, even if their signatures are the same
= help: consider casting both fn items to fn pointers using `as fn(usize)`
C++
void ptr_arg(void (*f)(unsigned)) {
f(5);
}
template<typename T>
void dyn_arg(T f) {
f(5);
}
template<void (*f)(unsigned)>
void tpl_arg() {
f(5);
}
void caller() {
ptr_arg(fn1);
dyn_arg(fn1);
tpl_arg<fn1>();
}
Rust
fn ptr_arg(f: fn(usize)){
f(5);
}
fn dyn_arg(f: &dyn Fn(usize)){
f(5);
}
fn tpl_arg(f: impl Fn(usize)){
f(5);
}
pub fn caller(){
ptr_arg(fn1);
dyn_arg(&fn1);
tpl_arg(fn1);
}
We talked about:
Send complaints to
admin@stickman.hu
alex@voidcomputing.hu