Unfortunately, what you are asking for is impossible with the traditional interface of smart pointers.
The issue is one of lifetime. A weak_ptr
cannot be use to access the object directly, because it does not guarantee that said object will live long enough: the object might be pulled right from under your feet.
Example:
int main() {
std::shared_ptr<int> sp(new int(4));
std::weak_ptr<int> wp(sp);
if (not wp.expired()) {
sp.reset();
std::cout << *wp << "\n"; // Access WP ? But there is nothing there!
}
}
Thus, for better or worse, there is no other choice than recovering a shared pointer from the weak pointer any time you actually need to access the object without controlling the duration of this access.
This last point, however, is our clue. A simple idea being to write a well-behaved client of weak_ptr
yourself and change the way it allows the external world to access the data. For example:
template <typename T>
class very_weak_ptr {
public:
very_weak_ptr() {}
explicit very_weak_ptr(std::weak_ptr<T> wp): _wp(wp) {}
template <typename F>
void apply(F&& f) {
std::shared_ptr<T> sp = _wp.lock();
f(sp.get());
}
private:
std::weak_ptr<T> _wp;
}; // class very_weak_ptr
Note: there is one remaining flaw, enable_shared_from_this
allows to recover a std::shared_ptr<T>
from the very instance of T
; you can add a compile time check on T
to prevent usage of this class with such objects.