template< class U, class E >
unique_ptr( unique_ptr<U, E>&& u ) noexcept;(6)
I find that unique_ptr<T[],D> has many constructors.But I don't know how to create a unique_ptr<T[],D> with function(6).Could you tell me how to call it?Thanks.
Reference:https://en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr
CodePudding user response:
unique_ptr
cannot be copied, so doesn't have a copy constructor. Constructors 5 and 6 are move constructors, which remove pointer ownership from original object and give it to new one.
unique_ptr( unique_ptr&& u ) noexcept; // (5) (constexpr since C 23)
template< class U, class E >
unique_ptr( unique_ptr<U, E>&& u ) noexcept; // (6) (constexpr since C 23)
In example the up6b
and up6d
are using the call to that function.
After the call, the smart pointers up6a
and up6c
do not point at object they were pointing before.
std::cout << "Example constructor(6)...\n";
{
std::unique_ptr<Foo, D> up6a(new Foo, d); // D is copied
std::unique_ptr<Foo, D> up6b(std::move(up6a)); // D is moved
std::unique_ptr<Foo, D&> up6c(new Foo, d); // D is a reference
std::unique_ptr<Foo, D> up6d(std::move(up6c)); // D is copied
}
Most common occurrence of move constructor invocation before C 17 was the initialization with make_unique
. You easily can do this:
std::unique_ptr<int[]> a(new int[10]);
std::unique_ptr<int[]> b(std::move(a));
But if you're trying to use make_unique , the latter needs invocation of specialization for an array allocation.
std::unique_ptr<int[]> b = std::make_unique<int[]>(10);
Note, that this isn't necessary invoke move constructor mentioned above.
CodePudding user response:
You could use make_unique
as shown below:
auto ptr = std::make_unique<int[]>(2);
Or
If you want to pass a custom deleter then one way would be to use std::function
as shown below:
auto ptr = std::make_unique<int[]>(2);
//here we use lambda as a deleter
std::unique_ptr<int[], std::function<void(int[])>> PTR(new int[2](), [](int*p)->void
{
std::cout<<"lambda called"<<std::endl;
delete[]p ;
});
std::unique_ptr<int[], std::function<void(int[])>> P2(std::move(PTR));
//or more readable
//auto P2 = std::move(PTR);
Using a separate function instead of lambda
is also possible and trivial as shown below:
//use a free function as deleter
void func(int p[])
{
std::cout<<"func called"<<std::endl;
delete[]p ;
}
int main()
{
auto ptr = std::make_unique<int[]>(2);
std::unique_ptr<int[], std::function<void(int[])>> PTR(new int[2](), func);
std::unique_ptr<int[], std::function<void(int[])>> up6b(std::move(PTR));
//or more readable
//auto up6b = std::move(PTR);
}