
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<observer<node>> children; void add_child(observer<node> child) { children.push_back(child); } void remove_child(observer<node> child) { children.erase(find(begin(children), end(children), child)); } }; And a contrived usage example: node a, b, c; b.set_parent(a); // conversion from `T&` c.set_parent(b); observer_ptr<node> x = c.get_parent(); if (x) // conversion to `bool` { observer<node> y = x->get_child(0); assert(y == c); // comparison with `T&` y->set_parent(a); b.set_parent(y); // conversion from `observer<T>` to `observer_ptr<T>` } A project with a working implementation <https://github.com/hpesoj/cpp-observer/blob/master/api/observer.hpp> and full test suite <https://github.com/hpesoj/cpp-observer/blob/master/tests/observer_tests.cpp> can be found here <https://github.com/hpesoj/cpp-observer>. Regards, Joseph