Skip to content

Why is operator= (impl_ptr<U, D, C>&& u) templated? #15

Description

@meator

Under two circumstances can two distinct instantiations of impl_ptr have a copier function convertible to the other impl_ptr? This copy assignment operator is templated, but I can't see a situation where two distinct impl_ptr instantiations could be used in an assignment.

I have discovered this problem as a result of my testing. I get why a single deleter function can be used for different types (the types could have inheritance relations and virtual destructors), but having compatible copier functions is weird. Even if such case would exist, what is

return impl_ptr(
    base_type::ptr_ ? copier_(base_type::ptr_.get()) : nullptr,
    base_type::ptr_.get_deleter(),
    copier_);

supposed to do in that case?

Let's consider the following example impl_ptr<BaseType, BaseDeleter, BaseCopier>{} = impl_ptr<DerivedType, BaseDeleter, BaseCopier>{}; DerivedType * is convertible to BaseType *. They have virtual destructors, so a shared BaseDeleter can be used.

Type requirements are satisfied for operator=, so it proceeds into the clone(). The clone calls a impl_ptr<DerivedType>(BaseType *, BaseDeleter function, BaseCopier function). Derived type cannot be trivially constructed from a pointer to BaseType (and even if it had a converting constructor, clone() would still fail, because BaseType * cannot be converted to DerivedType * without a cast (which would likely lead to UB)). Also, there is no constructor of impl_ptr accepting a templated pointer, copier function and a deleter function.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions