Как я могу сделать shared_ptr из непрозрачного указателя typedef? (или: как я могу "развернуть" typedef?)
Если у вас есть непрозрачный указатель typedef, есть ли способ динамически ссылаться на указанный тип, скажем, для использования в шаблонах? Например, скажем, у вас есть что-то вроде этого:
struct Foo; // Forward declared struct
typedef Foo* FooPtr; // Opaque pointer
Поскольку типы интеллектуальных указателей являются шаблонами в терминах типа указателя, чтобы определить std::shared_ptr
этого, кажется, что вы должны сказать:
std::shared_ptr<struct Foo> theSharedPtr;
Есть ли способ определить такой указатель без "ручного" разворачивания непрозрачного указателя typedef? Я чувствую, что, должно быть, мне не хватает чего-то очевидного, но вы можете представить что-то подобное (обратите внимание: они не работают):
std::shared_ptr<*FooPtr> theSharedPointer;
// or
std::shared_ptr<pointedto(FooPtr)> theSharedPointer;
Мне кажется, что это должно быть возможно. Я что-то упускаю? Я чувствую, что это надвигающийся момент лба-призрака...
РЕДАКТИРОВАТЬ: Еще несколько раз, но в общем случае shared_ptr<T>
хочет взять sizeof(T)
. Вы можете обойти это, предоставив конструктору конструктор. Я подозреваю, что это делает это немного краевым случаем, но по-прежнему кажется, что со всеми типами конфликтов в С++ я должен "разворачивать" тип указателя, не делая этого вручную.
Ответы
Ответ 1
В С++ 11:
#include <type_traits>
typedef std::shared_ptr< std::remove_pointer< FooPtr >::type > theSharedPtr;
В С++ 03 вы можете использовать boost::remove_pointer
точно так же.
Если вы не хотите включать boost, запись метафайла remove_pointer
довольно проста:
template<class T> struct remove_pointer;
template<class T> struct remove_pointer<T*> { typedef T type; };
Ответ 2
Да, поскольку вы уже используете возможности С++ 11, вы можете сделать это с помощью свойств типа. В частности, используя std::remove_pointer
:
std::remove_pointer<Foo*>::type; // Foo
Конечно, вам нужно будет указать стандартный стандартный заголовок, который:
#include <type_traits>
чтобы использовать его.
Ответ 3
Есть ли способ определить такой указатель без "ручного" разворачивания непрозрачного указателя typedef?
#include <type_traits>
std::shared_ptr<std::remove_pointer<FooPtr>::type> theSharedPointer;
кажется, что в общем случае shared_ptr<T>
хочет взять sizeof(T)
.
Он (вероятно) не нуждается в размере; но для его инициализации необходимо создать дебит, для которого тип должен быть завершен.