Is there any interest in non-owning pointer-like types?
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 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*`.
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.
Just to give you an idea of the current syntax, here is a simple tree node
type (where the nodes do not own their children) implemented using
`observer_ptr` and `observer`:
class node
{
public:
node() = default;
node(node const&) = delete;
node& operator=(node const&) = delete;
node(node&&) = delete;
node& operator=(node&&) = delete;
void set_parent(observer_ptr<node> new_parent) {
if (parent) parent->remove_child(*this);
parent = new_parent;
if (parent) parent->add_child(*this);
}
observer_ptr<node> get_parent() const {
return parent;
}
size_t get_child_count() const {
return children.size();
}
observer<node> get_child(size_t index) const {
return children[index];
}
private:
observer_ptr<node> parent;
vector
On February 1, 2017 2:47:54 AM EST, Joseph Thomson
For some time, I have been developing a pair of non-owning pointer-like types that I am currently calling `observer_ptr` and `observer`.
[snip]
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*`.
Can observer_ptr refer to no object? If not, why not just use T &? If so, why not just use optional<T>?
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.
How is this better than T &? -- Rob (Sent from my portable computation device.)
Hi,
Can observer_ptr refer to no object? If not, why not just use T &? If so, why not just use optional<T>?
As far as i understood it, it is still assignable, unlike T&. For me, the biggest problem of the proposal is that observer_ptr<T> is implicitely constructed from T&. In my code I often use: Foo a; Bar b(&a);//&a signals that b only references to a, but does not copy it. Now, when I write Bar b(a); //so is a now copied? While the interface is clearer in documentation, the usage is less clear! Best, Oswin
Quick note: I just subscribed to the list, and perhaps because I had "digest mode" switched on until just now, this was the first reply I received. Are there any other replies I haven't seen? On Wed, Feb 1, 2017 at 6:24 PM, Oswin Krause < Oswin.Krause@ruhr-uni-bochum.de> wrote:
Hi,
Can observer_ptr refer to no object? If not, why not just use T &? If
so, why not just use optional<T>?
As far as i understood it, it is still assignable, unlike T&.
`observer_ptr<T>` can be null; `observer<T>` cannot. `T&` is not the same in a number of ways: - `T&` cannot be "rebound" after construction. - `T&` makes containing classes non-copy assignable by default - `T&` cannot be stored in arrays - `T&` cannot be stored in containers (though I saw maybe this is a feature being added to the C++ standard?) - `T&` has value assignment and comparison semantics (they operate on the referenced value); the observer types have reference (pointer-like) assignment and comparison semantics. They behave very differently with algorithms and containers ( `reference_wrapper` has reference assignment semantics, which makes it work properly in containers, but it still has value comparison semantics. Essentially, `T&` (and `reference_wrapper<T>`) is not a pointer type, and has totally different semantics. `observer_ptr` and `observer` have pointer semantics and are useful where pointers would be useful. For me, the biggest problem of the proposal is that observer_ptr<T> is
implicitely constructed from T&. In my code I often use:
Foo a; Bar b(&a);//&a signals that b only references to a, but does not copy it.
Now, when I write
Bar b(a); //so is a now copied?
While the interface is clearer in documentation, the usage is less clear!
I personally have used this pattern in code before without confusion: bar(foo const& f) : m_f(&f) {} Indeed, the documented interface is clearer if you use `observer<foo const>`, but the calling code looks the same. I did anticipate that this might be a problem for some people (though I am personally comfortable with it). If this is a widespread concern, the implicit conversion from `T&` could be removed `make_observer` would become the recommended way to create an `observer`: Bar b(make_observer(a));
On Wed, Feb 1, 2017 at 11:24 AM, Oswin Krause
For me, the biggest problem of the proposal is that observer_ptr<T> is implicitely constructed from T&. In my code I often use:
Foo a; Bar b(&a);//&a signals that b only references to a, but does not copy it.
Now, when I write
Bar b(a); //so is a now copied?
While the interface is clearer in documentation, the usage is less clear!
IMO using pointers instead of references to indicate something isn't copied is bad practice.. the language is C++, not C. -- Olaf
On 2017-02-01 12:02, Olaf van der Spek wrote:
On Wed, Feb 1, 2017 at 11:24 AM, Oswin Krause
wrote: For me, the biggest problem of the proposal is that observer_ptr<T> is implicitely constructed from T&. In my code I often use:
Foo a; Bar b(&a);//&a signals that b only references to a, but does not copy it.
Now, when I write
Bar b(a); //so is a now copied?
While the interface is clearer in documentation, the usage is less clear!
IMO using pointers instead of references to indicate something isn't copied is bad practice.. the language is C++, not C.
This is not a C vs C++ thing. But assume it was. How would you indicate that in C++? It should be clear without looking at the reference whether it is okay for a to go out of scope before b or not.
On Wed, Feb 1, 2017 at 12:39 PM, Oswin Krause
On 2017-02-01 12:02, Olaf van der Spek wrote:
On Wed, Feb 1, 2017 at 11:24 AM, Oswin Krause
wrote: For me, the biggest problem of the proposal is that observer_ptr<T> is implicitely constructed from T&. In my code I often use:
Foo a; Bar b(&a);//&a signals that b only references to a, but does not copy it.
Now, when I write
Bar b(a); //so is a now copied?
While the interface is clearer in documentation, the usage is less clear!
IMO using pointers instead of references to indicate something isn't copied is bad practice.. the language is C++, not C.
This is not a C vs C++ thing.
But assume it was. How would you indicate that in C++? It should be clear without looking at the reference whether it is okay for a to go out of scope before b or not.
There's no way to indicate that, AFAIK. -- Olaf
On Feb 1, 2017, at 12:47 AM, Joseph Thomson
wrote: 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*`:
From my own experience, which includes writing my own version of exactly what you are describing and using it extensively in a large code base, I wholeheartedly agree with your sentiment and would welcome a standardized version of this. Just as std::unique_ptr and std::shared_ptr explicitly document their semantics, so too does observer_ptr, therefore making the code clearer to readers, users, and maintainers. Large code bases are always maintained by more than one person, and unless everyone agrees on the meaning of T* there can be confusion, subtle errors, and maintenance problems. The idea of an observer_ptr class avoids that and enables legacy code to be transformed at will. If it would be helpful, I would be happy to contribute anything from my own incarnation of an observer_ptr. Perhaps merging ideas would ensure that the API handles use cases well. Something that you did not mention that I have found useful is a make_observer() function for construction. This is mostly useful to explicitly construct an observer when that helps code clarity. Given the increased clarity and decreased ambiguity I have seen in my code when using this (isn’t that ultimately the goal of the STL and other designed libraries?), I have always wondered about the antipathy this idea faces, so I hope your proposal makes better progress. Cheers, Brook
On Wed, Feb 1, 2017 at 11:07 PM, Brook Milligan
On Feb 1, 2017, at 12:47 AM, Joseph Thomson
wrote: 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*`:
From my own experience, which includes writing my own version of exactly what you are describing and using it extensively in a large code base, I wholeheartedly agree with your sentiment and would welcome a standardized version of this. Just as std::unique_ptr and std::shared_ptr explicitly document their semantics, so too does observer_ptr, therefore making the code clearer to readers, users, and maintainers. Large code bases are always maintained by more than one person, and unless everyone agrees on the meaning of T* there can be confusion, subtle errors, and maintenance problems. The idea of an observer_ptr class avoids that and enables legacy code to be transformed at will.
Exactly. I have heard it suggested that once all other uses are covered by high-level types, the only use case left for `T*` is as a non-owning pointer. Even ignoring the real safety benefits a well-designed "observer" type brings, this idea is flawed because: 1. This is just a convention; no one is forced to follow it. 2. Even if everyone did follow it, legacy code will still use `T*` for other purposes. 3. Even if all legacy code were updated, low level code still uses `T*` for other purposes. If it would be helpful, I would be happy to contribute anything from my own
incarnation of an observer_ptr. Perhaps merging ideas would ensure that the API handles use cases well.
While I was just floating the idea and a review process has not officially started, I would be happy to hear any ideas you have. Have you seen my implementation that I linked to in my OP? Something that you did not mention that I have found useful is a
make_observer() function for construction. This is mostly useful to explicitly construct an observer when that helps code clarity.
My messages are moderated as I am a new subscriber to the list, so they may not have gone through yet, but I have mentioned that I have a `make_observer` function. If people feel that implicit conversion from `T&` is bad, it could even be the primary way to construct an `observer`. Given the increased clarity and decreased ambiguity I have seen in my code
when using this (isn’t that ultimately the goal of the STL and other designed libraries?), I have always wondered about the antipathy this idea faces, so I hope your proposal makes better progress.
Indeed. I was surprised when I found out the C++ standards committee was so hostile to the idea. I'm glad that people seem receptive to the idea here.
On 1/31/2017 11:47 PM, Joseph Thomson wrote:
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 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`.
When referring to 'T*' I think you should always use the terminology 'pointer' rather than 'reference'. By mixing the two you are confusing terminology, which I believe should always be distinct because a pointer and a reference are syntactically two different things in C++. snipped...
There is already an observer_ptr proposed for c++17.
http://en.cppreference.com/w/cpp/experimental/observer_ptr
On 1 February 2017 at 17:22, Edward Diener
On 1/31/2017 11:47 PM, Joseph Thomson wrote:
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 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`.
When referring to 'T*' I think you should always use the terminology 'pointer' rather than 'reference'. By mixing the two you are confusing terminology, which I believe should always be distinct because a pointer and a reference are syntactically two different things in C++.
snipped...
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman /listinfo.cgi/boost
On 1 February 2017 at 22:30, Richard Hodges wrote:
There is already an observer_ptr proposed for c++17.
No there isn't. The presence of something in a TS does not imply it has been proposed for C++17 (or any later standard). Even if it had been proposed, it's not part of the C++17 draft, which is supposed to be feature-complete. IIRC the only pieces of the Library Fundamentals TS v2 proposed for C++17 were gcd and lcm, everything else that made it into C++17 had been in Library Fundamentals TS v1 for some time and wasn't new in v2. Most of the new stuff in v2 needs more time to bake.
On 01/02/2017 07:47, Joseph Thomson wrote:
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 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 ... 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. 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. The GSL is a *much* better home for it than Boost because then you'll 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. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
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
On Thu, Feb 2, 2017 at 6:18 AM, Niall Douglas
wrote: 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
here instead. I don't think that exactly accurate. Rather it is that the GSL's
On 01/02/2017 07:47, Joseph Thomson wrote: proposal 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&)`. We need a proposal to change experimental::observer_ptr :)
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*` 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. 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.
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
(null_ptr); // compiles fine; run-time error I prefer also a not null smart pointer that takes this as a
Le 02/02/2017 à 02:15, Joseph Thomson a écrit : precondition. Requiring the class to check the parameter is not nullptr (as gsl::not_null does) is more than what I need.
`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
instantiation. The GSL is a *much* better home for it than Boost because then you'll
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
` etc. are broken; `not_null ` is of little value IMO, and may be conceptually broken too; honestly, the only useful case is `not_null `, and that currently has big issues with its design too. `observer` and `observer_ptr` are essentially `maybe_null` and `not_null` with clearer design goals and a fixed interface.
In reverse order ;-) Vicente
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 :)
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. Sorry, one additional comment. AFAIK, the GSL is aimed at those writing new C++ code, those updating old C++ code, and those making low-level C++ code safer. For example, `owner` is for use where something like `unique_ptr` cannot be used (either legacy code, or perhaps the library implementation of `unique_ptr` itself!)
There is only one proper way to represent the concept of a T that might not
be a T: optional<T>, so I think you are defining your objects backward. The
"top level" type should be observer<T>, and if you want to support the
concept of nullness, use optional
On Fri, Feb 3, 2017 at 1:17 PM, David Stone
There is only one proper way to represent the concept of a T that might not be a T: optional<T>, so I think you are defining your objects backward. The "top level" type should be observer<T>, and if you want to support the concept of nullness, use optional
. This is a much more consistent way to treat nullness throughout the language, rather than special-casing it for every type.
I actually agree with you from an ideological perspective, but practical
implications drove me to my current design.
My original goal was to create a better interface for `not_null
Using optional does not imply any overhead. You simply provide a
specialization for optional
On Sat, Feb 4, 2017 at 2:59 PM, David Stone
Using optional does not imply any overhead. You simply provide a specialization for optional
. You make optional a friend of observer<T>, and create a private constructor that acts as the back door to allow your type to store a nullptr inside it to represent the empty state. Then the only way to get in this state is through optional, so users of the type never see that such a state is possible.
This is quite true. I did consider this, but for some reason dismissed it. But I guess this optimization would be allowable under the as-if rule http://en.cppreference.com/w/cpp/language/as_if? Of course, this is contingent on `observer<T>` becoming part of the C++ standard.
The behavior of operator< is a little trickier. That being said, I do not believe that this type should have operator<. This type is not usable as an iterator, which is the only situation where operator< makes sense for pointer types. Instead, I would just specialize std::less (which I see you delegate to in your operator<) to allow use in std::map. Then the question of the performance of optional's operator< goes away, because it is not defined.
Sounds reasonable. I only defined the operators to allow storage in
ordered associative containers, but you are right that this only requires a
specialization of `less`.
I have a minor gripe with `optional
I'll just throw my 2cts in for consideration: I have implemented something called `object_ref` as part of my type safe library (github.com/foonathan/type_safe). It seems similar to the discussed `observer`. `object_ref` is basically a guaranteed non-null pointer. I think something like that is definitely useful, as references have weird semantics. On the other hand I don't think having `observer_ptr` as simply a pointer like type is that useful. An optional observer is better, as a properly designed optional can provide stuff like value_or()/map() etc which makes handling the null case easily. That's why I've implemented `optional_ref` as part of type safe. Jonathan
On Thu, Feb 2, 2017 at 6:18 AM, Niall Douglas
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.
The GSL is a *much* better home for it than Boost because then you'll 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.
I have just written up a proposal for inclusion of these types in the GSL, which you can find here: https://github.com/hpesoj/cpp-observer/blob/master/GSL-PROPOSAL.md While I don't want to appropriate the Boost mailing list for unrelated purposes, I thought I would post this here since I am still not entirely sure where I should be proposing this. My proposal would pretty much look the same whoever I pitched it to. And perhaps those involved in this thread are interested anyway. I'd be glad to hear any opinions. p.s. I am no longer doing funny things with implicit conversion from `T&`.
On Thu, Feb 2, 2017 at 6:18 AM, Niall Douglas
The GSL is a *much* better home for it than Boost because then you'll 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.
For those who are interested, I have included `observer<T>` (but not `observer_ptr<T>`) as part of a proposal regarding the recommended use of pointers over at the C++ Core Guidelines https://github.com/isocpp/CppCoreGuidelines. If you feel so inclined, you can continue the discussion in the issue I created. I have taken on board some of the feedback I received in this thread, so thanks very much. Issue: https://github.com/isocpp/CppCoreGuidelines/issues/847 Proposal: https://github.com/hpesoj/gsl-pointers
Naming:
- I think pointer or reference like things should be named _ptr or
_ref etc. (In comparison, optional and any can be null, but own their
value, they don't reference an external value.)
- 'observer' has already been taken by the Gang of Four as a design
pattern. Unfortunately. We could re-take the term, but it does add
confusion.
- I've suggested cadged_ptr in the past - it is not a great word, as
it it not very common, but it is actually the right meaning.
And by not being common, it means we can imbue it with whatever
meaning we'd like. In that sense it is a perfectly cromulent word.
Tony
On Thu, Feb 9, 2017 at 8:08 AM, Joseph Thomson via Boost
On Thu, Feb 2, 2017 at 6:18 AM, Niall Douglas
wrote: The GSL is a *much* better home for it than Boost because then you'll 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.
For those who are interested, I have included `observer<T>` (but not `observer_ptr<T>`) as part of a proposal regarding the recommended use of pointers over at the C++ Core Guidelines https://github.com/isocpp/CppCoreGuidelines. If you feel so inclined, you can continue the discussion in the issue I created. I have taken on board some of the feedback I received in this thread, so thanks very much.
Issue: https://github.com/isocpp/CppCoreGuidelines/issues/847 Proposal: https://github.com/hpesoj/gsl-pointers
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
<snip>, In that sense it is a perfectly cromulent word.
Tony
LOL Regarding context:
- I've suggested cadged_ptr in the past - it is not a great word, as it it not very common, but it is actually the right meaning. And by not being common, it means we can imbue it with whatever meaning we'd like. In that sense it is a perfectly cromulent word.
That's actually a very good point worth considering.
On 2/9/2017 1:56 PM, Gottlob Frege via Boost wrote:
Naming:
- I think pointer or reference like things should be named _ptr or _ref etc. (In comparison, optional and any can be null, but own their value, they don't reference an external value.)
I agree that adding _ptr to something that takes the form of a pointer is a good idea.
- 'observer' has already been taken by the Gang of Four as a design pattern. Unfortunately. We could re-take the term, but it does add confusion.
I see no confusion using a term which has been mentioned as a design pattern.
- I've suggested cadged_ptr in the past - it is not a great word, as it it not very common, but it is actually the right meaning.
I do not think it is necessary to use a fairly obscure word as opposed to a more common term, unless that common term is misleading.
And by not being common, it means we can imbue it with whatever meaning we'd like. In that sense it is a perfectly cromulent word.
Tony
On Thu, Feb 9, 2017 at 8:08 AM, Joseph Thomson via Boost
wrote: On Thu, Feb 2, 2017 at 6:18 AM, Niall Douglas
wrote: The GSL is a *much* better home for it than Boost because then you'll 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.
For those who are interested, I have included `observer<T>` (but not `observer_ptr<T>`) as part of a proposal regarding the recommended use of pointers over at the C++ Core Guidelines https://github.com/isocpp/CppCoreGuidelines. If you feel so inclined, you can continue the discussion in the issue I created. I have taken on board some of the feedback I received in this thread, so thanks very much.
Issue: https://github.com/isocpp/CppCoreGuidelines/issues/847 Proposal: https://github.com/hpesoj/gsl-pointers
On 10 Feb 2017 5:16 a.m., "Edward Diener via Boost"
Naming:
- I think pointer or reference like things should be named _ptr or _ref etc. (In comparison, optional and any can be null, but own their value, they don't reference an external value.)
I agree that adding _ptr to something that takes the form of a pointer is a good idea. I am not opposed to this nomenclature. One of the reasons I avoided the `_ptr` suffix was my concern that people would reflexively reject the idea of a pointer-like type that has no null state and is constructible only from `T&`. In my view, the feature that *makes* a pointer-like type is reference semantic comparison (as opposed to value semantic)... and maybe the presence of `*` and `->` operators. So I'm fine with this naming convention if others are. - 'observer' has already been taken by the Gang of Four as a design
pattern. Unfortunately. We could re-take the term, but it does add confusion.
I see no confusion using a term which has been mentioned as a design pattern. I am personally comfortable with the name, but I do see the argument about the potential for confusion. A rose by any other name would smell as sweet. - I've suggested cadged_ptr in the past - it is not a great word, as
it it not very common, but it is actually the right meaning.
I do not think it is necessary to use a fairly obscure word as opposed to a more common term, unless that common term is misleading. I initially read that as `caged_ptr`. I looked up the definition, and it does seem to have the right meaning. If such an uncommon word is undesirable, perhaps `obseved_ptr` or `watched_ptr` would be preferable (the "-ed" form of the veb matches `shared_ptr`).
On 10/02/2017 12:24, Joseph Thomson via Boost wrote:
I initially read that as `caged_ptr`. I looked up the definition, and it does seem to have the right meaning. If such an uncommon word is undesirable, perhaps `obseved_ptr` or `watched_ptr` would be preferable (the "-ed" form of the veb matches `shared_ptr`).
At the risk of devolving into a bikeshed, I don't really like anything that implies observing or watching unless it has the semantics of weak_ptr and knows when it is no longer pointing to a valid object. How about borrowed_ptr, unbound_ptr, irresponsible_ptr, unowned_ptr, or not_null_ptr? (Though a shorter typedef probably should be encouraged in practice or people would likely just stick with *.)
On Fri, Feb 10, 2017 at 7:59 AM, Gavin Lambert via Boost < boost@lists.boost.org> wrote:
On 10/02/2017 12:24, Joseph Thomson via Boost wrote:
I initially read that as `caged_ptr`. I looked up the definition, and it does seem to have the right meaning. If such an uncommon word is undesirable, perhaps `obseved_ptr` or `watched_ptr` would be preferable (the "-ed" form of the veb matches `shared_ptr`).
At the risk of devolving into a bikeshed, I don't really like anything that implies observing or watching unless it has the semantics of weak_ptr and knows when it is no longer pointing to a valid object.
How about borrowed_ptr, unbound_ptr, irresponsible_ptr, unowned_ptr, or not_null_ptr? (Though a shorter typedef probably should be encouraged in practice or people would likely just stick with *.)
A previous name I used was `indirect`, to give it an air of pointer-ness without using the terms "pointer" or "reference" (though it doesn't have a `_ptr` suffix). If we're being creative, the name could emphasise how the pointee is liable to die before the pointer itself. volatile_ptr transient_ptr mercurial_ptr unsafe_ptr unstable_ptr
On Fri, Feb 10, 2017 at 3:12 AM, Joseph Thomson via Boost
On Fri, Feb 10, 2017 at 7:59 AM, Gavin Lambert via Boost < boost@lists.boost.org> wrote:
On 10/02/2017 12:24, Joseph Thomson via Boost wrote:
I initially read that as `caged_ptr`. I looked up the definition, and it does seem to have the right meaning. If such an uncommon word is undesirable, perhaps `obseved_ptr` or `watched_ptr` would be preferable (the "-ed" form of the veb matches `shared_ptr`).
At the risk of devolving into a bikeshed, I don't really like anything that implies observing or watching unless it has the semantics of weak_ptr and knows when it is no longer pointing to a valid object.
How about borrowed_ptr, unbound_ptr, irresponsible_ptr, unowned_ptr, or not_null_ptr? (Though a shorter typedef probably should be encouraged in practice or people would likely just stick with *.)
A previous name I used was `indirect`, to give it an air of pointer-ness without using the terms "pointer" or "reference" (though it doesn't have a `_ptr` suffix). If we're being creative, the name could emphasise how the pointee is liable to die before the pointer itself.
volatile_ptr
volatile int * ptr; // a volatile pointer Rule 5 about naming - avoid "spoken ambiguity" - If I say to another dev "you need to use a volatile pointer here" did I mean volatile_ptr or volatile Foo * ?
transient_ptr
I kinda like that one.
mercurial_ptr unsafe_ptr unstable_ptr
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On Feb 9, 2017, at 6:59 PM, Gavin Lambert via Boost
How about borrowed_ptr, unbound_ptr, irresponsible_ptr, unowned_ptr, or not_null_ptr? (Though a shorter typedef probably should be encouraged in practice or people would likely just stick with *.)
Consider nonnull_ptr in place of not_null_ptr. Josh
On Mon, Feb 13, 2017 at 10:15 PM, Josh Juran via Boost
On Feb 9, 2017, at 6:59 PM, Gavin Lambert via Boost
wrote: How about borrowed_ptr, unbound_ptr, irresponsible_ptr, unowned_ptr, or not_null_ptr? (Though a shorter typedef probably should be encouraged in practice or people would likely just stick with *.)
Consider nonnull_ptr in place of not_null_ptr.
Josh
notmy_ptr is another of my favourites :-)
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
I don't think observer and observer_ptr are the good names. Both are pointers as they have pointer semantics. I'll suggest not_null_ptr and observer_ptr I consider both to be pointer-like types because they implement `operator*` and have reference (pointer-like) semantics. But `observer` is not default constructible, constructible from `T*` or `nullptr_t`, and is not contextually convertible to `bool`. I chose the name `observer` because it conveys intent (to observe something), and I felt it was appropriate to append `_ptr` to the type that is constructible from a pointer (because thus has a null state). The types are inherently similar, so I feel they should have similar names. I dislike the name `not_null_ptr` because it conveys no intent (there is more than one use for a non-owning pointer to a single object), and because it makes it seem completely unrelated to `observer_ptr`. I'm confused. observed_ptr is part of the C++ Fundamental TS v2. Why do you say that it was rejected? I was informed by the author of the proposal that the committee had made it clear that they were not interested in an "observer" pointer in any form. Perhaps this is not accurate, as someone else on this thread suggested. 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? I added this because I believed it to be reasonable. The reason is that it discourages the use of raw pointer, which is not conceptually type safe and can be error prone. However, after someone pointed out that implicit conversion from `T&` makes the intentions of the function taking an `observer_ptr` unclear, I feel that it might be safer to make the conversion explicit. `make_observer` would be the standard way to construct an `observer`, essentially replacing the `&` operator in this context. Mixed comparisons naturally follow from implicit conversions, but they would be removed if the conversions were made explicit. 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 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); The entire point of `observer` is to avoid making assumptions, and to have the type system enforce preconditions at compile-time. By allowing construction from `T*`, the compile-time type-safety of `observer` is lost. This is one of the major issues I have with `gsl::not_null` (though it has many other problems). And yes, the user has to dereference a pointer to convert it to an `observer`. It is commonly understood that dereferencing a null pointer is UB, and this can be tested for with static analysis tools. There is no need to design more UB into types that are supposed to be more high-level and type-safe than the C-style options (e.g. pointers). 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 have three options for my proposal, all recommended as the best avenue by different people: the C++ standard, Boost, and the GSL. I'm not sure which one to persue. I'm glad you think that the idea is worth proposing though :) 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 `get_pointer` is a relatively minor design detail that isn't fundamental to the proposal. I wouldn't be devastated by a `get` member function. Thanks for taking the time to look at everything in detail!
participants (16)
-
Brook Milligan
-
charleyb123 .
-
David Stone
-
Edward Diener
-
Gavin Lambert
-
Gottlob Frege
-
Jonathan Müller
-
Jonathan Wakely
-
Joseph Thomson
-
Josh Juran
-
Niall Douglas
-
Olaf van der Spek
-
Oswin Krause
-
Richard Hodges
-
Rob Stewart
-
Vicente J. Botet Escriba