Search code examples
c++pointerssmart-pointersimplicit-conversionlanguage-design

Smart pointers cannot be used as raw pointers automatically?


I'm trying to convert codes to use smart pointers instead of raw pointers. But was wondering - is it really not possible for smart pointers to be used as raw pointers?

In this example:

#include <iostream>
#include <string>
#include <memory>

void printer(int* x)
{
    std::cout << "x = " << x << std::endl;
}

int main()
{   
    auto x = std::make_unique<int>(5);
    printer(x);
    return 0;
}

I get an error:

In function 'int main()': 14:14: error: cannot convert
'std::unique_ptr<int, std::default_delete<int> >' to 'int*' for argument '1'
to 'void printer(int*)' 

How should this be coded? Thanks!


Solution

  • There cannot be an implicit conversion because an implicit conversion doesn't have context to do the right thing. printer takes a non-owning pointer, but what about other functions that need to take ownership? For instance

    void kill(int *p) { delete p; }
    

    Silently doing the conversion when calling kill(p); would be the wrong thing! It will lead to a double delete. The pointer has no way to know it should stop owning the object, it has to be told via a call to release. Anything else would be wrong.

    Since smart pointers are all about enforcing explicit ownership semantics, the conversion to a raw pointer needs to be explicit too, and have a name that conveys how the ownership is affected.