Option<T&> specialization
NathanSWard opened this issue · 2 comments
Is your feature request related to a problem? Please describe.
I absolutely love using the STX library. However, I always run into a problem when I want to return an optional reference to something, and do not have the provided facilities. For example, I have a map class map<int, ExpensiveType>
. I want to have my lookup
function return a reference to the value if the key exists, and None if the key does not exist. Being able to return stx::Option<ExpensiveType&>
would allow me to maintain my functional programming approach to my code instead of returning a raw pointer or throw exception, etc...
Describe the solution you'd like
Create a template specialization for stx::Option<T&>
that under that hood only holds a pointer to the T.
I would strongly argue that stx::Option<T&>
should not be re-assignable into order to mimic reference semantics and this avoids the debate on weather the assignment operator should assign through to the T. Also, the interface of Option<T&>
would be limited when compared to the non-reference version. E.g. replace
and unwrap_or_default
would not be available for the Option<T&>
interface.
Describe alternatives you've considered
The only other option to achieve the following is stx::Option<stx::Ref<T>>
however, this is not optimal as you can represent the Option reference as just a pointer instead of a reference wrapper and a bool.
Additional context
I have a branch of STX where I implement the Option<T&>
specialization and would gladly create a PR in the case this feature is considered a good idea to add.
Note: I would also consider extending this to include Result<T&, E>
, Result<T, E&>
, and Result<T&, E&>
specialization. However, as of right now, I believe Option<T&>
has many more use cases and is quite practical/trivial to implement.
Thanks, Nathan!
I've been considering adding it. But I've been holding back cos I didn't feel a specialization would be a good idea, considering the number of methods it has. Duplicating these methods will be error-prone. I'd argue that the semantics should be rebind.
Nonetheless, I'd love to see your PR and will be happy to take a look into it and consider it.
Also, in the case of the pointer representation, I'd recommend a pointer and a bool
, or std::reference_wrapper
and a bool
. Considering that nullptr dereference is UB, meaning that we can't predict what behaviour would occur on all systems, assuming a system decides to proceed in this scenario, and an Option<T&>
tries to bind to the result of such dereferencing, the address of the l-value ref will be nullptr
, which we'll also be using as a sentinel value. It is in fact error-prone for the general-purpose use-case (I might be wrong).
This is a part of the sentinel-based code we're trying to avoid with the Option
and Result
monadic types.
I'll be closing this as stale