我正在试图弄清楚是否可以创建一个指向不同类型的共享指针数组。 例如,类似的东西:
vector<shared_ptr<**???**>> v;
v.push_back(shared_ptr<int>(new int));
v.push_back(shared_ptr<MyClass>(new MyClass()));
或在不知道其类型的情况下传递shared_ptr
的任何其他方式。
答案 0 :(得分:27)
更安全的类型可能是:
/// header #include <boost/variant.hpp>
typedef boost::variant < boost::shared_ptr < T1 >, boost::shared_ptr < T2 >, ... > VariantT;
std::vector < VariantT > container;
container.push_back ( boost::shared_ptr < T1 > ( new T1 ) ); // or boost::make_shared
container.push_back ( boost::shared_ptr < T2 > ( new T2 ) ); // or boost::make_shared
答案 1 :(得分:22)
假设您要存储不继承公共类的对象,最简单的方法是使用boost::any
。
您仍然需要确定每个索引中存储的每个对象的类型(即能够执行正确的boost::any_cast
)。
你应该这样做,而不是存储指向void
的指针。这是最接近语义正确的存储方式&#34;你知道类型的东西,但编译器没有&#34;#34;这意味着在检索值时有一个演员。
虽然(any
和void
指针)将以相同的方式工作(指针放在一边),但如果转换为错误的类型,any
将抛出bad_any_cast
异常(IIRC),使用void
指针时,您将获得未定义的行为。对coliru的简单尝试产生了a segfault。
答案 2 :(得分:5)
正如任何基本指针类型都可转换为void*
一样,任何shared_ptr
都会转换为shared_ptr<void>
:
vector<shared_ptr<void>> v;
v.push_back(make_shared<int>());
v.push_back(make_shared<MyClass>());
您现在拥有vector
完全类型擦除的共享指针。但是,你无法做很多有趣的事情:你必须知道哪些类型存储在vector
的哪些插槽中才能将它们转换回来:
auto intptr = static_pointer_cast<int>(v[0]);
auto myclass_ptr = static_pointer_cast<MyClass>(v[1]);
所以尽管可能这样做,但它并不是非常有用,可能表明设计已经破碎。