Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make a shared_ptr from an opaque pointer typedef? (or: how can I "unwrap" typedef?)

Tags:

c++

If you have an opaque pointer typedef, is there a way to dynamically refer to the pointed-to type, say, for use in templates? For instance, say you have something like this:

struct Foo; // Forward declared struct
typedef Foo* FooPtr; // Opaque pointer

Because the smart pointer types are templates in terms of the pointer-to type, to define a std::shared_ptr of this, it seems that you have to say:

std::shared_ptr<struct Foo> theSharedPtr;

Is there any way to define such a pointer without "manually" unwrapping the opaque pointer typedef? I feel like I must be missing something obvious here, but you might imagine something like these (note: these do not work):

std::shared_ptr<*FooPtr> theSharedPointer;
// or
std::shared_ptr<pointedto(FooPtr)> theSharedPointer;

I feel like this should be possible. Am I missing something? I feel like this is an impending forehead-smacking moment...

EDIT: Noodling around some more, it appears that, in the common case, shared_ptr<T> wants to take the sizeof(T). You can get around this by providing a deleter to the constructor. I suspect this makes this a bit of an edge case, but it still seems like with all the type wrangling in C++, I should be able to "unwrap" a pointer type without doing so by hand.

like image 961
ipmcc Avatar asked Apr 03 '14 13:04

ipmcc


People also ask

What is the purpose of the shared_ptr <> template?

std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer.

What is shared_ptr?

The shared_ptr type is a smart pointer in the C++ standard library that is designed for scenarios in which more than one owner might have to manage the lifetime of the object in memory.

What happens when shared_ptr goes out of scope?

The smart pointer has an internal counter which is decreased each time that a std::shared_ptr , pointing to the same resource, goes out of scope – this technique is called reference counting. When the last shared pointer is destroyed, the counter goes to zero, and the memory is deallocated.

Can you return a shared_ptr?

So the best way to return a shared_ptr is to simply return by value: shared_ptr<T> Foo() { return shared_ptr<T>(/* acquire something */); };


1 Answers

In C++11:

#include <type_traits>

typedef std::shared_ptr< std::remove_pointer< FooPtr >::type > theSharedPtr;

In C++03 you can use boost::remove_pointer in the exact same way.

If you don't want to include boost, writing a remove_pointer metafunction is quite easy:

template<class T> struct remove_pointer;
template<class T> struct remove_pointer<T*> { typedef T type; };
like image 114
sbabbi Avatar answered Sep 22 '22 21:09

sbabbi