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 don't think observer and observer_ptr are the good names. Both are
Le 01/02/2017 à 08:47, Joseph Thomson a écrit : Hi, thanks for bringing these classes to boost ML discussion. pointers as they have pointer semantics. I'll suggest not_null_ptr and observer_ptr
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 proposal here instead.
The `observer_ptr<T>` class template is a pointer-like type that does not do any resource management, and is intended to be used in place of `T*` wherever `T*` is used as a non-owning reference to an object of type `T`. `observer_ptr<T>` has three main advantages over `T*`:
1. `T&` is implicitly convertible to `observer_ptr<T>` which, unlike `T*`, makes it *type-safe*. `T*` can represent things that are not conceptually objects of type `T`: arrays, strings, iterators. No implicit conversion from `T*` means that these things cannot implicitly convert to `observer_ptr<T>`. Pointers aren't even required to point to valid objects (e.g. a past-the-end iterator). Conversely, in a well-formed program, `T&` is *always* a valid object of type `T`. 2. `observer_ptr<T>` documents its purpose. This is really a side-effect of it being type-safe (a type should have a single, specific purpose), but it's worth mentioning. Conversely, when you see `T*`, it may not be immediately obvious what it represents. 3. `observer_ptr<T>` has a minimal interface, which makes it harder to misuse than `T*`; for example, `observer_ptr<T>` has no pointer arithmetic operators, no array subscript operator, no conversion to `void*`. So you have added the implicit conversion from T& to the FTSV2 observed_ptr. Why implicit? You have added mixed comparisons, between observed_ptr<T1> and T2. Have you added them because the conversion was implicit? Could you show a concrete and real a use case?
The `observer<T>` class template is a counterpart to `observer_ptr<T>` that has *no null state*; it cannot be default constructed, constructed from `nullptr_t` or constructed from `T*`, and it does not contextually convert to `bool`. The only way to create an `observer<T>` is from `T&`. This allows a "not null" precondition to be enforced at compile-time, rather than having to worry about pointers being null at run-time. Wondering if an explicit conversion from T*, requiring that T* is not nullptr is not useful. This is C++. When the user knows that the pointer is not null, it seams natural that
I'm confused. observed_ptr is part of the C++ Fundamental TS v2. Why do you say that it was rejected? the user can construct an observer<T> if (T* ptr = f()) g(observer<T>(ptr)); observer<T>(ptr) will be UB if ptr is equal to nullptr. Or are you suggesting that the user de-reference the pointer to get a reference if (T* ptr = f()) g(observer<T>(*ptr); or with a factory if (T* ptr = f()) g(not_null(ptr); I believe it is worth proposing the not-null observer pointer to the C++ standard. And why not the construction from T& for observer_ptr<T>. I don't share the get_pointer concern. smart pointer have a get function . However I believe it is worth proposing an explicit conversion in addition to the get function Vicente