There seem to be some edge-cases when using enabled_shared_from_this. For example:
boost shared_from_this and multiple inheritance
Could shared_from_this be implemented without using enable_shared_from_this? If so, could it be made as fast?
A shared_ptr is 3 things. It is a reference counter, a destroyer and an owned resource.
When you make_shared, it allocates all 3 at once, then constructs them in that one block.
When you create a shared_ptr<T> from a T*, you create the reference counter/destroyer separately, and note that the owned resource is the T*.
The goal of shared_from_this is that we can extract a shared_ptr<T> from a T* basically (under the assumption it exists).
If all shared pointers where created via make_shared, this would be easy (unless you want defined behavior on failure), as the layout is easy.
However, not all shared pointers are created that way. Sometimes you can create a shared pointer to an object that was not created by any std library function, and hence the T* is unrelated to the shared pointer reference counting and destruction data.
As there is no room in a T* or what it points to (in general) to find such constructs, we would have to store it externally, which means global state and thread safety overhead and other pain. This would be a burden on people who do not need shared_from_this, and a performance hit compared to the current state for people who do need it (the mutex, the lookup, etc).
The current design stores a weak_ptr<T> in the enable_shared_from_this<T>. This weak_ptr is initialized whenever make_shared or shared_ptr<T> ctor is called. Now we can create a shared_ptr<T> from the T* because we have "made room" for it in the class by inheriting from enable_shared_from_this<T>.
This is again extremely low cost, and handles the simple cases very well. We end up with an overhead of one weak_ptr<T> over the baseline cost of a T.
When you have two different shared_from_this, their weak_ptr<A> and weak_ptr<B> members are unrelated, so it is ambiguous where you want to store the resulting smart pointer (probably both?). This ambiguity results in the error you see, as it assumes there is exactly one weak_ptr<?> member in one unique shared_from_this<?> and there is actually two.
The linked solution provides a clever way to extend this. It writes enable_shared_from_this_virtual<T>.
Here instead of storing a weak_ptr<T>, we store a weak_ptr<Q> where Q is a virtual base class of enable_shared_from_this_virtual<T>, and does so uniquely in a virtual base class. It then non-virtually overrides shared_from_this and similar methods to provide the same interface as shared_from_this<T> does using the "member pointer or child type shared_ptr constructor", where you split the reference count/destroyer component from the owned resource component, in a type-safe way.
The overhead here is greater than the basic shared_from_this: it has virtual inheritance and forces a virtual destructor, which means the object stores a pointer to a virtual function table, and access to shared_from_this is slower as it requires a virtual function table dispatch.
The advantage is it "just works". There is now one unique shared_from_this<?> in the heirarchy, and you can still get type-safe shared pointers to classes T that inherit from shared_from_this<T>.
Yes, it could use global hash tables of type
unordered_map< T*, weak_ptr<T> >
to perform the lookup of a shared pointer from this.
#include <memory>
#include <iostream>
#include <unordered_map>
#include <cassert>
using namespace std;
template<class T>
struct MySharedFromThis {
static unordered_map<T*, weak_ptr<T> > map;
static std::shared_ptr<T> Find(T* p) {
auto iter = map.find(p);
if(iter == map.end())
return nullptr;
auto shared = iter->second.lock();
if(shared == nullptr)
throw bad_weak_ptr();
return shared;
}
};
template<class T>
unordered_map<T*, weak_ptr<T> > MySharedFromThis<T>::map;
template<class T>
struct MyDeleter {
void operator()(T * p) {
std::cout << "deleter called" << std::endl;
auto& map = MySharedFromThis<T>::map;
auto iter = map.find(p);
assert(iter != map.end());
map.erase(iter);
delete p;
}
};
template<class T>
shared_ptr<T> MyMakeShared() {
auto p = shared_ptr<T>(new T, MyDeleter<T>());
MySharedFromThis<T>::map[p.get()] = p;
return p;
}
struct Test {
shared_ptr<Test> GetShared() { return MySharedFromThis<Test>::Find(this); }
};
int main() {
auto p = MyMakeShared<Test>();
assert(p);
assert(p->GetShared() == p);
}
Live Demo
However, the map has to be updated whenever a shared_ptr is constructed from a T*, and before the deleter is called, costing time. Also, to be thread safe, a mutex would have to guard access to the map, serializing allocations of the same type between threads. So this implementation would not perform as well as enable_shared_from_this.
Update:
Improving on this using the same pointer tricks used by make_shared, here is an implementation which should be just as fast as shared_from_this.
template<class T>
struct Holder {
weak_ptr<T> weak;
T value;
};
template<class T>
Holder<T>* GetHolder(T* p) {
// Scary!
return reinterpret_cast< Holder<T>* >(reinterpret_cast<char*>(p) - sizeof(weak_ptr<T>));
}
template<class T>
struct MyDeleter
{
void operator()(T * p)
{
delete GetHolder(p);
}
};
template<class T>
shared_ptr<T> MyMakeShared() {
auto holder = new Holder<T>;
auto p = shared_ptr<T>(&(holder->value), MyDeleter<T>());
holder->weak = p;
return p;
}
template<class T>
shared_ptr<T> MySharedFromThis(T* self) {
return GetHolder(self)->weak.lock();
}
Live Demo
Related
I wanted to ask if there is a smart pointer that could take in any class in its template and then any operations done with such pointer would result in a thread-safe operation.
Basically an idea would be that such pointer would automatically hold an internal lock during a scope and release it when the pointer goes out of scope.
Use case would be for example to pull such pointer from a static, pre-allocated array into some scope and perform thread-safe operations inside that scope on the object itself.
I tried to find a C++ library/feature that could perhaps allow for some thread-safe mutation on objects by wrapping it into a single smart pointer object.
if there is a smart pointer that could take in any class in its template and then any operations done with such pointer would result in a thread-safe operation.
No, there is no such smart pointer in the C++ standard.
I don't think that's possible in the "usual" smart pointer sense, because when doing ptr->something() or (*ptr).something(), the operator-> and operator* methods are called, they return the pointer/reference and then something is invoked, so you don't have any way to know when to unlock the mutex after the operation has been done. This can be worked around through proxy objects, but that's another can of worms, especially when mixed with usage of auto.
Moreover, on a higher level this is rarely a kind of thread-safety guarantee one actually needs. In a codebase of ours someone once wrote a wrapper for std::map with a mutex protecting some common mutation operations; this was eminently useless for several reasons. The most obvious was that operator[] returns a reference anyway (so, you get a reference that may be instantly invalidated by someone else calling e.g. erase()); but most importantly, people did stuff like if (!map.count(key)) { map[key].do_something(); }, ignoring the fact that the result of count became stale immediately.
The takeaway here is that generally mutex-wrapping single operations on an objects doesn't gain you much: to actually work safely in a sane manner usually you need to take a mutex for a longer period, to ensure your code has a consistent snapshot of the protected object state.
A possibility to attack both these problems is to turn the whole thing to a different angle: you may wrap your object in an "escrow" object that forces you to take the mutex to access the data, but also think in terms of "doing all the operations where you need it" in a single "mutex-take". A sketch may be something like:
template<typename T>
class MutexedPtr {
std::mutex mtx;
std::unique_ptr<T> ptr;
public:
MutexedPtr(std::unique_ptr<T> ptr) : ptr(std::move(ptr)) {}
template<typename FnT>
void access(FnT fn) {
std::lock_guard<std::mutex> lk(mtx);
fn(*ptr);
}
};
The usage should be something like:
MutexedPtr<Something> ptr = ...;
...
ptr.access([&](Something &obj) {
// do your stuff with obj while the mutex is taken
});
whether this is something that could be useful to your use case is up to you.
I wanted to ask if there is a smart pointer that could take in any class in its template and then any operations done with such pointer would result in a thread-safe operation.
Yes, that's possible. Here's a simple implementation:
#include <thread>
#include <mutex>
#include <cstdio>
template <class T>
struct SyncronizedPtrImpl {
private:
std::scoped_lock<std::mutex> lock;
T* t;
public:
SyncronizedPtrImpl(std::mutex& mutex, T* t) : lock(mutex), t(t) {}
T* operator->() const { return t; }
};
template <class T>
struct SyncronizedPtr {
private:
std::mutex mutex;
T* p;
public:
SyncronizedPtrImpl<T> operator->() {
return SyncronizedPtrImpl<T>{mutex, p};
}
SyncronizedPtr(T* p) : p(p) {}
~SyncronizedPtr() { delete p; }
};
int main() {
struct Foo {
int val = 0;
};
SyncronizedPtr ptr(new Foo);
std::thread t1([&]{
for (int i = 0; i != 10; ++i) ++ptr->val;
});
std::thread t2([&]{
for (int i = 0; i != 10; ++i) --ptr->val;
});
t1.join();
t2.join();
return ptr->val == 0;
}
I have a few classes which look like that:
struct equation {};
struct number: equation {
number(int n): value(n) {}
private:
int value;
};
struct operation: equation {
operation(const equation* left, const equation* right)
: left(left), right(right) {}
private:
std::unique_ptr<equation> left, right;
};
They are designed in a way that operation takes ownership on the pointers that are passed into constructor.
My question is how can I modify this class to be able to safely use it in a next manner:
operation op(new number(123), new number(456));
It seems to me that if the first object is created and the second one is not (say exception is thrown from number constructor) then it's a memory leak - nobody will ever delete a pointer to the first number.
What can I do with this situation? I do not want to allocate objects sequentially and delete them if something has failed - it's too verbose.
I do not want to allocate objects sequentially and delete them if something has failed - it's too verbose.
Yes. You just need to apply smart pointer idiom more thoroughly; more precisely, change the parameter type to std::unique_ptr, and use std::make_unique (since C++14) (instead of using new explicitly) to avoid this problem. e.g.
struct operation: equation {
operation(std::unique_ptr<equation> left, std::unique_ptr<equation> right)
: left(std::move(left)), right(std::move(right)) {}
private:
std::unique_ptr<equation> left, right;
};
then
operation op(std::make_unique<number>(123), std::make_unique<number>(456));
Note that the using of std::make_unique is important here, the raw pointer created inside std::make_unique is guaranteed to be managed by the returned std::unique_ptr; even the 2nd std::make_unique fails the
std::unique_ptr created by the 1st std::make_unique will see to it that the pointer it owns is destroyed. And this is also true for the case that the 2nd std::make_unique is invoked first.
Before C++14 you can make your own version of std::make_unique; a basic one is easy to write. Here's a possible implementation.
// note: this implementation does not disable this overload for array types
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
I know it sound absurd to use weak_ptrs with unique_ptrs, but bear with me please.
I have a set of widgets and animations that act on them. The widgets have a clear owner, who creates and destroys them. All the widgets are created, destroyed, animated in one thread, so one widget can't be destroyed while the animation code is running. As you can see, the widgets are are somehow shared with the animations, but the animation should stop if the widgets gets deleted.
The current approach is to use std::unique_ptr for the owners of the widgets and expose them as raw pointers to the animations. This makes very difficult finding/debugging dangling pointers. One proposal was to change to std::shared_ptr inside the owner class and expose std::weak_ptrs to the animations, but this will add some unwanted/unneeded overhead in the system.
Is it possible (a good idea?) to create some sort of weak_ptr on top of std::unique_ptr that just flags that the pointer was deleted? If yes, can you please suggest me some implementations with minimal overhead for single threaded usage.
EDIT:
One more clarification - the widgets are used in one thread, but the application has multiple threads. Also lots of animations run in parallel and each animation is updated 60 times/second. The overhead from std::shared_ptr/std::weak_ptr comes from the (atomic) counter used inside std::shared_ptr, that actually is not needed in this particular case.
EDIT:
I'm not asking if I can use std::weak_ptr with std::unique_ptr, I know this is not possible. I'm asking if it is a good idea/possible to build something with similar behavior as std::weak_ptr that can be paired with std::unique_ptr
No, you can't use std::weak_ptr with std::unique_ptr. You make it a std::shared_ptr and expose a std::weak_ptr, just like you said.
As far as the overhead of reference counting is concerned, I highly doubt that will be the bottleneck of your application, so profile and worry about that only when it becomes (probably never) so.
Sure, it's a reasonable idea. It provides control over the lifetime of the object while giving the subordinate threads the opportunity of detecting its disappearance.
Of course the lock() method of your weak objects will need to return something that does not itself allow re-sharing.
You can do this by encapsulating existing shared_ptr and weak_ptr objects.
A simple example:
#include <iostream>
#include <memory>
// some type we're going to use for testing
struct Foo {
~Foo() {
std::cout << "Foo destroyed" << std::endl;
}
void use() const {
std::cout << "using Foo" << std::endl;
}
};
// forward declaration
template<class T> struct weak_object_ptr;
// a pointer that keeps the object alive but is not itself copyable
template<class T>
struct keep_alive_ptr
{
// make it moveable
keep_alive_ptr(keep_alive_ptr&&) = default;
keep_alive_ptr& operator=(keep_alive_ptr&&) = default;
// provide accessors
T& operator*() const {
return *_ptr;
}
T* operator->() const {
return _ptr.get();
}
private:
// private constructor - the only way to make one of these is to lock a weak_object_ptr
keep_alive_ptr(std::shared_ptr<T> ptr)
: _ptr { std::move(ptr) }
{}
// non-copyable
keep_alive_ptr(const keep_alive_ptr&) = delete;
keep_alive_ptr& operator=(const keep_alive_ptr&) = delete;
friend weak_object_ptr<T>;
std::shared_ptr<T> _ptr;
};
// a weak reference to our shared object with single point of ownership
template<class T>
struct weak_object_ptr
{
weak_object_ptr(std::weak_ptr<T> w)
: _weak { std::move(w) }
{}
keep_alive_ptr<T> lock() const {
return keep_alive_ptr<T> { _weak.lock() };
}
private:
std::weak_ptr<T> _weak;
};
// a shared object store and lifetime controller
template<class T>
struct object_controller
{
// helpful universal constructor
template<class...Args>
object_controller(Args&&...args)
: _controller { std::make_shared<T>(std::forward<Args>(args)...) }
{}
weak_object_ptr<T> get_weak() const {
return weak_object_ptr<T> { _controller };
}
void reset() {
_controller.reset();
}
private:
std::shared_ptr<T> _controller;
};
// test
using namespace std;
int main(){
auto foo_controller = object_controller<Foo> {};
auto weak1 = foo_controller.get_weak();
auto weak2 = foo_controller.get_weak();
{
auto strong1 = weak1.lock();
strong1->use();
cout << "trying to destroy Foo\n";
foo_controller.reset();
auto strong2 = weak2.lock();
strong2->use();
cout << "strong2 going out of scope\n";
}
return 0;
}
expected output (note that the destruction of Foo takes place as early as it is legally allowed):
using Foo
trying to destroy Foo
using Foo
strong2 going out of scope
Foo destroyed
I often find myself wanting to write code like this:
class MyClass
{
public:
void addObject(std::unique_ptr<Object>&& newObject);
void removeObject(const Object* target);
private:
std::set<std::unique_ptr<Object>> objects;
};
However, much of the std::set interface is kind of useless with std::unique_ptrs since the lookup functions require std::unique_ptr parameters (which I obviously don't have because they're owned by the set itself).
I can think of two main solutions to this.
Create a temporary unique_ptr for lookup. For example, the above removeObject() could be implemented like:
void MyClass::removeObject(const Object* target)
{
std::unique_ptr<Object> targetSmartPtr(target);
objects.erase(targetSmartPtr);
targetSmartPtr.release();
}
Replace the set with a map of raw pointers to unique_ptrs.
// ...
std::map<const Object*, std::unique_ptr<Object>> objects;
};
However, both seem slightly stupid to me. In solution 1, erase() isn't noexcept, so the temporary unique_ptr might delete the object it doesn't really own, and 2 requires double the storage for the container unnecessarily.
I know about Boost's pointer containers, but their current features are limited compared to modern C++11 standard library containers.
I was recently reading about C++14 and came across "Adding heterogeneous comparison lookup to associative containers". But form my understanding of it, the lookup types must be comparable to the key types, but raw pointers aren't comparable to unique_ptrs.
Anyone know of a more elegant solution or an upcoming addition to C++ that solves this problem?
In C++14, std::set<Key>::find is a template function if Compare::is_transparent exists. The type you pass in does not need to be Key, just equivalent under your comparator.
So write a comparator:
template<class T>
struct pointer_comp {
typedef std::true_type is_transparent;
// helper does some magic in order to reduce the number of
// pairs of types we need to know how to compare: it turns
// everything into a pointer, and then uses `std::less<T*>`
// to do the comparison:
struct helper {
T* ptr;
helper():ptr(nullptr) {}
helper(helper const&) = default;
helper(T* p):ptr(p) {}
template<class U, class...Ts>
helper( std::shared_ptr<U,Ts...> const& sp ):ptr(sp.get()) {}
template<class U, class...Ts>
helper( std::unique_ptr<U, Ts...> const& up ):ptr(up.get()) {}
// && optional: enforces rvalue use only
bool operator<( helper o ) const {
return std::less<T*>()( ptr, o.ptr );
}
};
// without helper, we would need 2^n different overloads, where
// n is the number of types we want to support (so, 8 with
// raw pointers, unique pointers, and shared pointers). That
// seems silly:
// && helps enforce rvalue use only
bool operator()( helper const&& lhs, helper const&& rhs ) const {
return lhs < rhs;
}
};
then use it:
typedef std::set< std::unique_ptr<Foo>, pointer_comp<Foo> > owning_foo_set;
now, owning_foo_set::find will accept unique_ptr<Foo> or Foo* or shared_ptr<Foo> (or any derived class of Foo) and find the correct element.
Outside of C++14, you are forced to use the map to unique_ptr approach, or something equivalent, as the signature of find is overly restrictive. Or write your own set equivalent.
Another possibility, close to the accepted answer, but a little different and simplified.
We can exploit the fact that standard comparator std::less<> (with no template arguments) is transparent. Then, we can supply our own comparison functions in the global namespace:
// These two are enough to be able to call objects.find(raw_ptr)
bool operator<(const unique_ptr<Object>& lhs, const Object* rhs) {
return std::less<const Object*>()(lhs.get(), rhs);
}
bool operator<(const Object* lhs, const unique_ptr<Object>& rhs) {
return std::less<const Object*>()(lhs, rhs.get());
}
class MyClass
{
// ...
private:
std::set<std::unique_ptr<Object>, std::less<>> objects; // Note std::less<> here
};
You can try to use boost::multi_index_container with additional indexing by Object*.
Something like this:
typedef std::unique_ptr<Object> Ptr;
typedef multi_index_container<
Ptr,
indexed_by<
hashed_unique<Ptr>,
ordered_unique<const_mem_fun<Ptr,Object*,&Ptr::get> >
>
> Objects;
Fore more information see Boost Multi-index Containers documentation
Or may be you can use std::shared_ptr everywhere, or use raw pointers in set instead?
Why you need to lookup by raw pinter? If you store it anywhere and check that object with this pointer is valid then better to use std::shared_ptr for storing in container and std::weak_ptr for other objects. In this case before usage you don't need lookup by raw pointer at all.
While definitely a hack, I just realized it's possible to construct a temporary "dumb" unique_ptr with placement new and not risk de-allocation. removeObject() could be written something like this:
void MyClass::removeObject(const Object* target)
{
alignas(std::unique_ptr<Object>)
char dumbPtrData[sizeof(std::unique_ptr<Object>)];
objects.erase(
*::new (dumbPtrData) std::unique_ptr<Object>(const_cast<Object *>(target)));
}
This solution would work for std::unordered_set, std::map keys, and std::unordered_map keys as well, all using standard C++11 only, with practically zero unnecessary overhead.
UPDATE 2: Yakk is correct, there is no way to do this with standard C++11 containers without significant compromises. Either something will run in linear time in the worst case or there are those workarounds that you write in your question.
There are two workarounds that I would consider.
I would try a sorted std::vector, similarly to boost::container::flat_set. Yes, the inserts / erases will be linear time in the worst case. Still, it might be much faster than you probably think: Contiguous containers are very cache friendly compared to node based containers, such as std::set. Please read what they write at boost::container::flat_set. Whether this compromise is acceptable for you, I cannot tell / measure.
Others also mentioned std::share_ptr. I personally try to avoid them, mainly because "a shared pointer is as good as a global variable" (Sean Parent). Another reason why I don't use them is because they are heavy weight, partly because of all the multi-threading stuff that I usually don't need. However, boost::shared_ptr, when BOOST_SP_DISABLE_THREADS is defined, removes all that overhead associated with multi-threading. I believe using boost::shared_ptr would be the easiest solution in your case.
UPDATE: As Yakk kindly pointed out, my approach has linear time complexity... :(
(The first version.)
You can do it by passing a custom comparator to std::lower_bound(). Here is a rudimentary implementation how:
#include <algorithm>
#include <cassert>
#include <iostream>
#include <memory>
#include <set>
#include <string>
using namespace std;
template <typename T>
class Set {
private:
struct custom_comparator {
bool operator()(const unique_ptr<T>& a, const T* const & b){
return a.get() < b;
}
} cmp;
set<unique_ptr<T>> objects; // decltype at begin() and end()
// needs objects to be declared here
public:
auto begin() const -> decltype(objects.begin()) { return objects.begin(); }
auto end() const -> decltype(objects.end() ) { return objects.end(); }
void addObject(unique_ptr<T>&& newObject) {
objects.insert(move(newObject));
}
void removeObject(const T* target) {
auto pos = lower_bound(objects.begin(), objects.end(), target, cmp);
assert (pos!=objects.end()); // What to do if not found?
objects.erase(pos);
}
};
void test() {
typedef string T;
Set<T> mySet;
unique_ptr<T> a{new T("a")};
unique_ptr<T> b{new T("b")};
unique_ptr<T> c{new T("c")};
T* b_ptr = b.get();
mySet.addObject(move(a));
mySet.addObject(move(b));
mySet.addObject(move(c));
cout << "The set now contains: " << endl;
for (const auto& s_ptr : mySet) {
cout << *s_ptr << endl;
}
mySet.removeObject(b_ptr);
cout << "After erasing b by the pointer to it:" << endl;
for (const auto& s_ptr : mySet) {
cout << *s_ptr << endl;
}
}
int main() {
test();
}
You're using unique pinters here. This means, your set has unique ownership of objects. Now, this should mean that if object does exist, it's either in the set or you have unique pointer with it. You don't even need to look up the set in this case.
But to me it looks like it's not hte case. I suppose you're better off with shared pointer in this case. Just store shared pointers and pass them around since someone beside this set clearly stores them.
I love Boost's smart_ptr features and the ability to convert to and from a shared_ptr and weak_ptr, but since the reference count is not contained in the pointed class itself, the following code does not work (and it shouldn't).
A *a = new A;
shared_ptr<A> aPtr1(a);
{
shared_ptr<A> aPtr2(a);
// The reference counts of aPtr1 and aPtr2 are both 1.
} // At this point, `a` is destructed by aPtr2.
aPtr1->foo(); // And... SIGTERM
I believe the JUCE framework has this functionality. [ReferenceCountedObject and ReferenceCountedObjectPtr]
However, I'd rather use Boost for my application. Is it possible to allow Boost smart_ptrs to look for the reference count in the pointed class rather than the private boost::detail::shared_count instance?
Simple solution:
A *a = new A;
shared_ptr<A> aPtr1(a);
{
// construct new shared pointer from old one.
shared_ptr<A> aPtr2(aPtr1);
}
aPtr1->foo();
If you want something more complicated, see http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html :
The header <boost/enable_shared_from_this.hpp> defines the class template enable_shared_from_this. It is used as a base class that allows a shared_ptr to the current object to be obtained from within a member function.
Edit: I should have mentioned that enable_shared_from_this has some unfortunate issues with derivation. However, the following works with c++11; I didn't try it with boost but I suppose it should work there, too. I think it's a bit of a hack; using raw pointers when you use shared_ptr's is bound to end in tears:
struct X : std::enable_shared_from_this {
/* stuff */
};
struct Y : X {
/* stuff */
void yonly() {};
};
int main() {
Y* y = new Y;
shared_ptr<Y> sy(y);
sy->yonly();
{
auto sy2 = std::shared_ptr<Y>(y->shared_from_this(), y);
sy2->yonly();
}
std::cout << "Block ended" << std::endl;
return 0;
}
boost::intrusive_ptr likely fits your requirements.
To note however, with shared_ptr, you should construct them as follows:
shared_ptr<A> aPtr1 = boost::make_shared<A>();
This is not exception safe:
// call this as in shared_ptr<T> foo = create_intrusive_shared( new T(blah) );
// This takes ownership of the pointer you pass it.
template<typename T>
std::shared_ptr<T> create_intrusive_shared( T* t )
{
auto retval = std::shared_ptr<T>( t, []( T* cleanup )
{
if (cleanup)
cleanup->RemoveRef();
});
return retval;
}
// Call this if you have an existing instance of T, whose ownership is being
// maintained elsewhere. Do not call it with new T() as an argument, unless
// new instances of T are created with a 0 ref count
template<typename T>
std::shared_ptr<T> make_intrusive_shared( T* t )
{
if (t)
t->AddRef();
auto retval = create_intrusive_shared(t);
return retval;
}
Making them exception safe takes a bit more work. You will want to reimplement make_shared, but tag the resulting shared_ptr with a cleanup function.