On Thu, Feb 2, 2017 at 6:18 AM, Niall Douglas
For some time, I have been developing a pair of non-owning pointer-like types that I am currently calling `observer_ptr` and `observer`. I had planned to propose their addition to the C++ standard library, but I have been informed by the author of the original `observer_ptr` proposal http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4282.pdf that the ISO C++ committee has rejected his proposal and made clear that it feels there is no place in the standard library for such types, believing that this role is filled to a satisfactory degree by regular pointers. I wholeheartedly disagree with this assessment, so I am bringing my
On 01/02/2017 07:47, Joseph Thomson wrote: proposal
here instead.
I don't think that exactly accurate. Rather it is that the GSL's proposed schema of:
* owner<T> is an owning pointer * span<T> is a borrowed pointer/reference/view * C type pointers are non-owning, non-borrowed
As far as I understand it, `span<T>` is a view of objects over a range, in the vein of `array_view<T>`, and raw pointers are simply non-owning. I'm not sure what "borrowed" means in this context. ... has general wide agreement in principle, if not in exact
formulation. The Library Fundamentals TS v2 does have an observer_ptr in std::experimental, but there is general lack of sureness as to what it actually contributes when a non-annotated pointer according to the GSL schema is either an observer by definition, or unupgraded code.
That is just one of the benefits I listed (documentation of intent). The most benefit important IMO is *type-safety*, followed closely by a more minimal interface. The `observer_ptr<T>` in `std::experimental` only has type safety in one direction (conversion to `T*` is explicit), because the only way to construct it is from `T*`. Observers should preferably be constructed from `T&`, as this is a type-safe conversion. The `observer_ptr<T>` in `std::experimental` needs one change to make it type safe: change `make_observer(T*)` to `make_observer(T&)`. In my opinion, designating `T*` to mean "observer" would be okay in an ideal world (it still has far too general an interface for something that just observes), but the world isn't ideal. Not everyone reads the GSL guidelines, and those who do won't follow it to the letter, and even if they did there is still plenty of "unupgraded" code. Also, I think you too easily dismiss the benefit of being able to distinguish between un-upgraded and upgraded code; this sounds very useful if you ask me. So, to reiterate again, `observer_ptr`: - Allows upgraded code to be distinguished from un-upgraded code (this is more important than you might think) - Removes operations that are inappropriate for an observer type (pointer arithmetic, array subscript, conversion to `void*`) - Provides type safety by allowing construction from `T&` and disallowing construction from and conversion to `T*` Whether to allow implicit/explicit conversion from `T&` is a design detail. The benefits are there regardless. Also, it seems to me that the natural meaning of `T*` in C++ is as an iterator, not an observer: int arr[] = { 1, 2, 3 }; auto it = std::end(arr); // `decltype(it)` is `int*` I'd need a fair bit of convincing that observer<T> has merit in any form
except additional clarity to help demarcate unupgraded code from upgraded code. If that's your argument, and you're not doing funny things with implicit conversion from T& and other funny non-GSL semantics, I'd suppose this though I'd suggest you actually contribute it to GSL itself and persuade Neil to let it in.
`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
have Bjarne batting for it, plus static checking support from Microsoft in VS2017 and Google via clang-tidy. You'll also get a *huge* userbase almost instantly, because the GSL or rather one of its C++ 98 clones is seeing exponential growth recently. It's amazingly useful for upgrading ancient C++ codebases.
This would be good. If I brought this to the GSL, I would pretty much be
proposing that `not_null` is scrapped in favour of `observer` and
`observer_ptr`. `not_null<zstring>` is obsoleted by `string_view`;
`not_null