You can create the so called observer_ptr
trivially by creating a unique_ptr
with a NOP deleter.
template<typename T>
struct nop_deleter
{
void operator()(T*) const {}
};
template<typename T>
using observer_ptr = unique_ptr<T, nop_deleter>;
This will still have unique_ptr
's behavior, meaning it's move-only, while you'd want observer_ptr
to be copyable. Which leads us to a simpler implementation:
template<typename T>
using observer_ptr = T*;
This does everything you want. You can call it observer_ptr<int>
instead of int *
, because the latter is, of course, evil. It's copyable, and does nothing upon destruction.
I'm being facetious in the answer above, but hopefully, it'll demonstrate that observer_ptr
doesn't have much utility other than having a different name than a raw pointer type. There's nothing wrong in using a non-owning raw pointer.
You may argue that observer_ptr
conveys intent, but that argument is only valid if your code base contains instances of raw pointers that manage resources. Eliminate those and then a raw pointer will automatically mean observer_ptr
... without the fancy name.
If you absolutely must have the fancy name, and/or a distinct type, implementing it yourself should be easy.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…