Search code examples
c++c++11smart-pointersunique-ptr

pointer to const int using smart pointer


I am trying to create a smart pointer (unique_ptr) to a value returned as const int& but my issue can be summed up as easily as:

 const int value = 5;
 const int * ptr{nullptr};
 ptr = &value;

This works, and compile as expected. When trying to the same using smart pointer:

 const int value = 5;
 std::unique_ptr<const int> ptr{nullptr};
 ptr = &value;

With this I get the compile error:

no operator "=" matches these operands -- operand types are: std::unique_ptr<const int, std::default_delete<const int>> = const int *

Is it possible to get the same behaviour as normal C pointers?

EDIT: I see that my original question was too simplified: here is the bit more advanced version:

int value = 5;
const int& getValue(){
    return value;
};
std::unique_ptr<const int> ptr1{nullptr};
const int * ptr2{nullptr};

ptr1 = std::make_unique<const int>(getValue());
ptr2 = &getValue();
std::cout << "ptr1: " << *ptr1 << "\n";
std::cout << "ptr2: " << *ptr2 << "\n";
value++;
std::cout << "ptr1: " << *ptr1 << "\n";
std::cout << "ptr2: " << *ptr2 << "\n";

This prints out:

ptr1: 5
ptr2: 5

ptr1: 5
ptr2: 6

As you see the behaviour is a bit different, now I believe it is because make_unique makes a copy of the value in the pointed memory address


Solution

  • std::unique_ptr can't be assigned by raw pointer directly; you can use reset. But you shouldn't assign the address of value, (which is destroyed when get out of the scope automatically), std::unique_ptr will try to delete the pointer and that leads to UB.

    You might want

    int value = 5; // we'll constructor a new object, value doens't need to be const
    std::unique_ptr<const int> ptr{nullptr};
    ptr = std::make_unique<const int>(value); // construct a new object and pass the ownership to ptr
    

    EDIT

    For the purpose of using smart pointers,

    Smart pointers are used to make sure that an object is deleted if it is no longer used (referenced).

    You shouldn't use smart pointers if you don't want the smart pointer manage the object, or can't let the smart pointer own the object. For this special case, I think it's just fine to use raw pointer.