We need a proposal to change experimental::observer_ptr :)
That was my intention before I was informed by the proposal author that the proposal was a dead-end. I am not sure whether it would or would not be worth pursuing now. I agree we need this vocabulary type. GSL guidelines are for code that will be written from scratch with C++14/C++17. The reality is that we have tons of C++98 code. Pretending that T* is a not owning pointer because we have gsl::owner is not useful in a legacy code project. I'm not saying that gsl::owner is not useful. Totally agree. In addition, there is still more than one use for `T*` in the Core Guidelines (observer and "optional reference" parameter). I would rather look at some unfamiliar code and see `observer_ptr<T>` than see `T*` and have to consider whether or not the code is adhering to the guidelines. The guidelines also assume that all people follow the guidelines perfectly, and that the static analysis can catch all the "incorrect" uses of `T*`, and that all code has been upgraded. In my opinion, `observer` and `observer_ptr` embody the guidelines' own rules to "be type-safe" and "express intent". Whether to allow implicit/explicit conversion from `T&` is a design detail.
The benefits are there regardless.
Yes, I believe the implicit conversion could be questionable. Yes. I am increasingly feeling this way. `observer<T>` is similar to `not_null<T>`, in that it enforces a "not null"
precondition, except `observer<T>` does a much better job because it enforces the precondition at compile-time.
auto o = make_observer(null_ptr); // compile error: expects `T&` auto n = not_null
(null_ptr); // compiles fine; run-time error
I prefer also a not null smart pointer that takes this as a precondition. Requiring the class to check the parameter is not nullptr (as gsl::not_null does) is more than what I need. Disagree. As I said, better to enforce at compile-time using the type system. `observer` forces the user to dereference their pointer, which should be
flagged as unsafe by the static analyser if they don't check for null. `not_null` waits until compile-time to report the error, and makes it harder for a static analyser to catch the potential null pointer bug.
I have had a few discussions with Neil over at the GSL GitHub page about the purpose of `not_null`. Honestly, the design goals of `not_null<T>` seem unclear to me; it seems to be trying to do too many things at once, simultaneously trying to be a drop-in replacement for `T*` that enforces a "not null" precondition at run-time (it's meant to be able to hold any kind of pointer or pointer-like object), but also trying to be this high-level modern type that has compile-time type safety (it deletes various pointer arithmetic operations, and it has been seriously suggested that conversion from `T` should be explicit). It was initially meant to be compatible with smart pointers like `unique_ptr`, but this goal seems to have been all but abandoned after it was realised that this won't really work. It's also meant to be used in conjunction with strings, despite the fact that `string_view` is a much better alternative, and with the `owner` annotation, despite the fact that this will probably have the same conceptual problems as `unique_ptr`. If my ramblings sound confused, it's because I am confused, because `not_null` is confused.
Maybe we could have not_null<Ptr> that works for any pointer-like type, but
what I need today is not_null_ptr<T>.
Maybe it is worth providing a single not_null
`not_null` with clearer design goals and a fixed interface.
In reverse order ;-)
Yeah, I noticed that after I pressed send :)