я использую std::shared_ptr<T>
для многих разных типов. Так как я хочу хранить все эти разные shared_ptr
S в одном векторе, я думал, имея std::vector<std::shared_ptr<void> >
и приведение к и от void
если необходимо.
Я знаком со следующим использованием «голого указателя»
#include <iostream>
void print(void* void_ptr)
{
int* int_ptr = static_cast<int*>(void_ptr);
std::cerr << *int_ptr << std::endl;
}
int main()
{
int* int_ptr = new int(4);
void* void_ptr = static_cast<void*>(int_ptr);
print(void_ptr);
delete int_ptr;
}
Это работает безупречно с g++
и afaik это правильный способ сделать это, если у вас есть голые указатели. Но теперь я хочу иметь то же самое с std::shared_ptr
s.
#include <iostream>
#include <memory>
void print(std::shared_ptr<void> void_ptr)
{
std::shared_ptr<int> int_ptr = ??(void_ptr); // simple cast won't work
std::cerr << *int_ptr << std::endl;
}
int main()
{
std::shared_ptr<int> int_ptr = std::make_shared<int>(4);
std::shared_ptr<void> void_ptr = ??(int_ptr); // same problem here
print(void_ptr);
}
Это вообще возможно? Есть много разных типов, которые у меня есть shared_ptr
с, но эти типы имеют мало общего. Они не разделяют базовый класс или что-то в этом роде (если это единственный способ, я сделаю это, но это было бы определенно более круто с каким-то shared_ptr<void>
).
std::static_pointer_cast
выполняет эту функцию. Тем не менее, это, как правило, очень плохая идея — почему бы и нет boost::any
или же boost::variant
или что-то? Этот слабо типизированный и слабо реализованный код только укусит вас в задницу.
Лучшее решение вашей проблемы может быть стирание типа.
Видение как C ++ не позволяет неявное преобразование между шаблонами (даже если их аргументы являются конвертируемыми).
Итак, что вы можете сделать, это определить общий интерфейс, который вы будете хранить в своих контейнерах (operator*
а также operator->
для начала), а затем просто используйте тонкий шаблонный класс поверх shared_ptr для стирания типа.
Редактировать:
Как указано в вопросе @paercebal указал вам, shared_ptr
может выполнить стирание типа самостоятельно, когда параметр шаблона void
, Таким образом, вы должны изучить это также.