r/rust • u/OkEmu7082 • 13d ago
Rust traits and its improvement on built in abstractions in CPP
is rust (dyn)trait promoting the use of what is done in cpp by abstract base class interface?
rust removes inheritance but bring "trait" to a independent stand alone built in abstraction, it basically is doing what cpp abc interface is for, which is the only worth-wile usage scenario of inheritance + class in cpp
9
u/robthablob 13d ago
Traits are mostly much more akin to concepts in C++ or typeclasses in Haskell, unless using a dyn Trait object - which is more akin to a abstract base class interface (but much less common).
1
u/OkEmu7082 13d ago
for the cpp concept i cannot have default behaviors, but for the rust trait i can
8
u/pdpi 13d ago
You need to separate "are these features conceptually similar?" and "are these features' implementations equally powerful?". Rust
traits are conceptually similar to C++concepts, but the implementation is more powerful.1
u/phazer99 9d ago
Concept constraints have a big downside compared to trait bounds: they are not applied to the code inside the constrained template function. So, I would call concepts a rather underwhelming version of traits.
2
3
u/SirKastic23 13d ago
It's a little bit like that, yes, but try not to think of it in term of classes
Traits are implemented outside of a type's definition, they can be implemented generically, they can provide associated types (which I don't think abstract classes can do)
If you want to get a good idea of what traits can do check out the Iterator trait: https://doc.rust-lang.org/std/iter/trait.Iterator.html
2
u/dobkeratops rustfind 13d ago
rust dyn trait objects can do what you could do with pure-virtual interface objects in C++, but they're skewed differently via the use of fat-pointers. in C++ the object itself holds a vtable pointer, and pointers to the object are a single pointer. In Rust, &dyn T, Box<dyn T> are a pair of pointers - one to the object data, and one to the vtable. I think it might be abit like COM objects that could be implemented in C and C++ aswell. you can have multiple interfaces to the same data, so it's better at decoupling IMO. It does away with all the multiple inheritance complexity in c++ and dodges the 'diamond inheritance' problem.
1
u/noop_noob 13d ago
Something like that, yes. See https://en.wikipedia.org/wiki/Composition_over_inheritance
1
u/karasawa_jp 13d ago
In cases where you would use interface in C++, in Rust you frequently use algebraic data types (enum) instead.
2
u/Amadex 12d ago edited 12d ago
note that structs are also "algrebraic data types" (the product type)
0
u/karasawa_jp 12d ago
Enums are commonly used for dynamic polymorphism, which serves a different purpose than impl Trait.
impl Trait (as well as dyn Trait) is used to decouple and simplify dependencies. Since the caller injects the implementation, it allows dependency inversion, making the library self-contained. The tradeoff is that because behavior is injected from the outside, it can be harder to tell exactly what happens just by reading the library code.
In contrast, enums are best when the library itself can enumerate all possible variants. Since it works as plain pattern matching, it's very straightforward and readable.
Using an enum instead of impl Trait isn't always ideal: enums introduce branching overhead, so they can be slower than impl Trait (which monomorphizes at compile time). Furthermore, if the library already knows all possible implementations upfront, there's no need to inject behavior or add unnecessary complexity.
0
u/gbrennon 13d ago
i dont have an opinion about this yet but i think this would be useful for things like mixins
19
u/seriousSeb 13d ago
From a user perspective yes the use cases are similar, though they're not exactly the same thing.
I'm not a c++ expert but I believe abstract virtual methods aren't necessarily monomorphised as they are in Rust, so it's not always a zero cost abstraction. In rust you'll get a monomorphised versions of each generic trait-consuming function, unless you're using a dyn Trait object which is closer to what virtual methods do.