I'm interested in updating an old personal project to modern C++. I appreciate how RAII simplifies cleanup: instead of making a new
object and remembering to delete
it before every return point in a function, just make_unique
and it will be destroyed appropriately. But I have one nitpick when comparing the generated assembly.
Say there's a class method that replaces one of its unique_ptr
members with a new value:
// std::unique_ptr<int> MyClass::m_foo;
void MyClass::refresh_foo(int x) {
m_foo = std::make_unique<int>(x * 3 + 5);
}
This will create a new
int
, assign it to m_foo
, and then delete
the old value of m_foo
. But that's not quite the same as the old behavior, which could delete
the old value, then create a new
one and assign it to m_foo
:
// int *MyClass::m_foo;
void MyClass::refresh_foo(int x) {
delete m_foo;
m_foo = new int(x * 3 + 5);
}
From the Compiler Explorer, gcc, clang, and MSVC all generate less code for the old way than the new one. I understand why this is the case, since that's the order in which all expressions are evaluated; p = q;
has to construct q
first. And of course m_foo
had an invalid value in between the delete
and new
lines. But is there a way I'm missing to have unique_ptr
destroy its old value and then create a new one in one expression? A "replace_unique
"? Seems like it would be helpful when dealing with large objects so two of them don't needlessly coexist.
Edit: To be clear, I'm just using int
as a trivial example here. My actual use cases are with classes of my own or from a library. And m_foo.reset(new int(x * 3 + 5));
naturally has the same problem compared to the old way of doing things, since it too has to construct the new
int
before assigning it and delet
ing the previous one.