Search code examples
c++auto-ptr

Function taking a std::auto_ptr<Base> that can accept std::auto_ptr<Derived>


I am trying to create a function that takes an auto_ptr to Base class and I would like to call it with a auto_ptr to Derived class. However I am failing to get it done.

I have tried using it without a reference:

void function(std::auto_ptr<Base> ptr);

std::auto_ptr<Derived> derivedPtr( new ... )
function(derivedPtr); // error:  #348: more than one user-defined conversion from
                      // "std::auto_ptr<Derived>" to "std::auto_ptr<Base>" applies

And with a reference:

void function(std::auto_ptr<Base>& ptr);

std::auto_ptr<Derived> derivedPtr( new ... )
function(derivedPtr); //error:  #304: no instance of overloaded function "function" 
                      // matches the argument list

EDIT: I know auto_ptr is deprecated but I only have access to C++03 and cant access boost. So I would appreciate if the answers would focus on the question itself :) I also do understand the difference of a function taking a reference and a auto_ptr by value. In my actual code the function takes ownership of the auto_ptr so both are fine if I can get the conversion from Derived to Base working.


Solution

  • You can cast without ambiguity:

    function(static_cast<std::auto_ptr<Base> >(derivedPtr));
    

    Be aware that for this to work, Base must have a virtual destructor. Otherwise the code has undefined behavior.

    The reason for the ambiguity is as Arne says in his answer -- it's not obvious to the caller whether function takes a value or a reference, and therefore it's not obvious to the caller whether their auto_ptr will be released or not by making the call, and if it is released whether it's converted to a type that can correctly delete the pointer. The ambiguous conversion AFAIK is there to stop you writing such difficult code. By casting, you make it explicit in the calling code that derivedPtr is released.