how to make copy of unique_ptr wih custom deleter

  • A+
Category:Languages

I am getting compilation errors if I make a copy of unique_ptr with custom deleter . Please some one help me out .

#include <iostream> #include<memory> #include <algorithm> using namespace std;  auto del = [](int *p) { cout <<"obj deleted "<<endl;delete p;}; int main() {    unique_ptr<int, decltype(del)> p1(new int(10), del);    unique_ptr<int,decltype(del)> p2;    p2 = std::move(p1); } 

Errors:

C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/5.1.0/include/c++/tuple||In instantiation of 'constexpr std::_Head_base<_Idx, _Head, true>::_Head_base() [with unsigned int _Idx = 1u; _Head = <lambda(int*)>]':| C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/5.1.0/include/c++/tuple|353|required from 'constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl() [with unsigned int _Idx = 1u; _Head = <lambda(int*)>]'| C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/5.1.0/include/c++/tuple|202|required from 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl() [with unsigned int _Idx = 0u; _Head = int*; _Tail = {<lambda(int*)>}]'| C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/5.1.0/include/c++/tuple|602|required from 'constexpr std::tuple<_T1, _T2>::tuple() [with _T1 = int*; _T2 = <lambda(int*)>]'| C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/5.1.0/include/c++/bits/unique_ptr.h|158|required from 'constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr() [with _Tp = int; _Dp = <lambda(int*)>]'| F:/3d/C++CodeProject/Hello/main.cpp|10|required from here| C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/5.1.0/include/c++/tuple|59|error: use of deleted function '<lambda(int*)>::<lambda>()'| F:/3d/C++CodeProject/Hello/main.cpp|6|note: a lambda closure type has a deleted default constructor| C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/5.1.0/include/c++/bits/unique_ptr.h||In instantiation of 'std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Tp, _Dp>&&) [with _Tp = int; _Dp = <lambda(int*)>]':| F:/3d/C++CodeProject/Hello/main.cpp|11|required from here| C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/5.1.0/include/c++/bits/unique_ptr.h|252|error: use of deleted function '<lambda(int*)>&<lambda(int*)>::operator=(const<lambda(int*)>&)'| F:/3d/C++CodeProject/Hello/main.cpp|6|note: a lambda closure type has a deleted copy assignment operator| ||=== Build failed: 2 error(s), 8 warning(s) (0 minute(s), 1 second(s)) ===| 


The issue you're having with the declaration of p2 is that the type of the lambda is not default constructible. Therefore every declaration of the pointer type needs to have an instance of the deleter passed to it.

You can fix this by replacing the deleter lambda with an explicit functor struct that is default constructible. Then, each instance of the pointer type will be able to create its own instance of the deleter object.

struct MyDeleter {     void operator()(int* p){cout << "deleted" << endl; delete p;} };  int main() {     //don't need to specify an instance of the deleter since it is default_constructible.     unique_ptr<int, MyDeleter> p1(new int(10));      unique_ptr<int, MyDeleter> p2;     p2 = std::move(p1); } 

EDIT: as @super said, the issue with the assignment line would also be that (pre-c++20) lambdas are also not CopyAssignable. The functor method I posted above fixes both issues.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: