On Friday, 18 May 2018 00:39:02 PDT
zongshe...@gmail.com wrote:
> I understand that this is disabled because unique_ptr<Derived> cannot
> implicitly converted to unique_ptr<Base> because copy constructor is
> deleted. But actually we could achieve this by the following member
> function template:
>
> template<typename Target, typename Deleter>
> operator my_unique_ptr<Target, Deleter>&()
> {
> static_assert(std::is_convertible_v<my_unique_ptr::pointer, typename
> my_unique_ptr<Target, Deleter>::pointer>, "cannot convert");
> return reinterpret_cast<my_unique_ptr<Target, Deleter>&>(*this);
> }
This only works if the internal storage of std::unique_ptr<Derived> and
std::unique_ptr<Base> are identical. That is not the case.
Your code breaks if Base and Derived have different top-of-structure addresses
in almost every single std::unique_ptr implementation. Try this:
struct Base { int i; };
struct OtherBase { int j; };
struct Derived : OtherBase, Base {};
Create a unique_ptr<Derived> and do your cast trick to convert it to
unique_ptr<Base> Then perform a comparison of the two .get(). You'll see the
comparison will fail.
In fact, you don't need a unique_ptr to do this test. Just try this:
auto dptr = new Derived;
auto base = reinterpret_cast<Base *&>(dptr);
assert(base == dptr);
This assertion will fail.
--
Thiago Macieira - thiago (AT)
macieira.info - thiago (AT)
kde.org
Software Architect - Intel Open Source Technology Center