Общие ptr для A и B не связаны между собой.
Что делает общий ptr, так это предоставляет конвертирующий конструктор. Пока типы указателей могут быть преобразованы, он принимает как raw-pointer-to, так и shared-ptr-to.
Shared ptr type стирает способ окончательного уничтожения и сохраняет указатель, так что это действительно не сложно.
Как именно это будет работать, будет зависеть от того, как хранятся данные и что делает Wrapper.
Но:
template<class T>
struct Wrapper {
template<class U>
Wrapper(Wrapper<U>);
};
в основном это. Может быть, какой-нибудь SFINAE, чтобы получить более ранние ошибки.
...
Поскольку вы действительно добавили детали в комментарии, у вас есть:
template<class T>
struct RollbackElement : public T
как Wrapper
. Ответ: нет, вы не можете этого сделать.
Вы можете сделать:
template<class T>
struct RollbackElement : public std::any {
operator T&() {
return std::any_cast<T&>(*this);
}
};
, где вместо хранения фактического T
вы храните обертку для стирания типа вокруг T
.
template<class T>
struct RollbackElement : private std::any {
operator T&() {
return *get();
}
operator T const&() const {
return *get();
}
RollbackElement( T in ):
std::any(std::move(in)),
get_impl([](std::any& x)->T*{return std::any_cast<T*>(&x);})
{}
RollbackElement():RollbackElement({}) {}
template<class U>
RollbackElement( RollbackElement<U> const& o ):
std::any( static_cast<std::any const&>(o) ),
get_impl(o.get_impl)
{}
// note: due to quirks in `std::any`, a move ctor isn't safe
T* operator->() { return get(); }
T const* operator->() const { return get(); }
T* get() { return get_impl(*this); }
T const* get() const { return get_impl(const_cast<std::any&>(*this)); }
private:
std::function<T*(std::any&)> get_impl = {};
};
плюс любое увеличение на нем.
Хитрость в том, что ваше хранилище, std::any
, может хранить что угодно.
Мы храним, как добраться от std::any
до T*
в get_impl
.
Когда мы копируем RollbackElement
, мы копируем оба any (без приведения к конкретному типу) и get_impl
. Если другой откат имеет тип другого , мы полагаемся на конструктор преобразования std::function
, чтобы скорректировать возвращаемые указатели для нас.