In using move constructor/assignment of std::unique_ptr
, can one assume that the underlying object is not reallocated in memory, such that a raw pointer to it remains valid?
Consider the following program:
#include <memory>
#include <utility>
#include <iomanip>
#include <iostream>
template <class T>
struct A {
std::unique_ptr<T> data = nullptr;
T *p;
template <class... U>
A(U&&... x) : data{std::make_unique<T>(std::forward<U>(x)...)}, p{data.get()} { }
};
int main()
{
A<int> v{2};
std::cout << std::hex << v.p << std::endl;
A<int> w{std::move(v)};
std::cout << w.p << std::endl;
}
Here w
is constructed with the default move constructor of A
, which calls the move constructor of std::unique_ptr
.
It appears by the output that the underlying allocated int
is not really moved in memory, so the default move constructor correctly initialized w.p
as identical to v.p
. Trying with other types for T
gives analog result.
Can one assume that the move constructor of std::unique_ptr
does not really move the object in memory, so that in the above program the default move constructor is correct? Is that specified by the language?
Or to avoid a dangling pointer must one add a move constructor explicitly like the following?
A(A<T>&& other) : data{std::move(other.data)}, p{data.get()} { }
Aucun commentaire:
Enregistrer un commentaire