Closed danakj closed 1 year ago
The markers however make it much easier to work with references.
For calling void f(Tuple<i32&, i32&>)
and void g(Tuple<i32, i32>)
, f(sus::tuple(i, i))
and g(sus::tuple(i, i))
both do the right thing.
But then the caller doesn't see the reference being captured so maybe that's worse in C++ land anyway.
One thing missing without sus::vec()
is a way to type-deduce an empty vector.
We can sus::Vec(a, b, c) and deduce Vec<decltype(a)> which is good! But what about empty?
Maybe we need a generic sus::marker::empty
or something?
Another option but kinda weird is
template <class T = sus::marker::Undeduced>
class Vec {
Vec(); // works with Undeduced.
Vec(T); // doesn't cause you can't construct Undeduced.
Vec(Vec<Undeduced>); // An empty Vec.
};```
Dropping tuple() is bad because it handles reference types well, so that we can construct a Tuple over references without writing the whole type out.
So as a compromise position, added type deduction guides for Tuple (and Vec and Array and Option) which do not preserve references but can be used for simply constructing concrete types without writing out the full template. And allow Tuple to convert when its contents can convert.
But keeping the tuple()
deduction helper as well, as it supports references by deferring until an actual Tuple type is known.
Rust
C++
This would be nicer
but
tuple()
returns a marker that deduces types forvec()
this lets you pass it heterogenous types and it figures out the actual thing later to convert them all to but constructing aTuple
idk maybe you want to use the types you have. without... writing them all out 😐 tbh i never writevec(...)
even. it's very nice forsome()
andnone()
but forVec
just writing it out seems.. fine maybe i should kill the marker types except for some/none and ok/err.i see
std::optional<T>
can construct fromstd::optional<U>
which ifOption
did,some(T)
could returnOption<T>
and then convert later toOption<U>
, instead of a marker type that deduces to theU
. this would be a lot more friendly with returning things but Rust's Option does not convert fromOption<T>
toOption<U>
. There's noimpl From<Option<U>> where T: From<U>
or something. otoh because it can hold refs/pointers, we really do probably want to allow convertingOption<Sub&>
toOption<Super&>
in the same way we did for Box. inheritance is A Thing.You can't construct an
Option<T>
fromnone()
though, unless it'snone<T>()
. But likestd::nullopt
, which is a marker type for none, we could have none() return a marker ifT
isn't specified butsome()
return anOption
. It's an asymmetry.Even more of an asymmetry is
Result<T, E>
, both ok() and err() know only one ofT
orE
so neither can actually make a Result. Marker types make sense there, so many they make sense for Option too.But for the containers, and tuples, they seem to be more trouble.