лямбда-удалитель для unique_ptr, вызывающий ошибку компиляции против функтора - PullRequest
0 голосов
/ 25 апреля 2018

Похоже на основной вопрос, но меня очень смущает.

Я обновлял нашу кодовую базу с VS2012 до VS2015, и у нас есть unique_ptr с пользовательским удалением, определенным так:

auto cpcdeleter = []( CP_CONVERT * ptr ) { KillCpConvert( &ptr ); };
unique_ptr<CP_CONVERT, decltype( cpcdeleter )> cpc;

...

cpc = unique_ptr<CP_CONVERT, decltype( cpcdeleter )>( CreateCpConvert(), cpcdeleter );

Я получаю сообщение об ошибке в VS2015 с жалобой на то, что у удалителя есть оператор удаленного назначения, поэтому он не может выполнить назначение. Это назначение отлично работало в VS2012, используя ссылочную перегрузку R-Value оператора =.

Все работает нормально, если вместо этого я определю удалитель как функтор:

struct CpDeleter 
{ 
  public: 
    void operator()(CP_CONVERT *ptr) const { KillCpConvert( &ptr ); } 
};

Теперь я прекрасно это делаю, но я был почти уверен, что использование лямбды должно работать. И это было до недавнего времени!

У кого-нибудь есть идеи?

РЕДАКТИРОВАТЬ: полная ошибка во всей его славе шаблона

c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1382): error C2280: 'openscheduleretrieve_ldlo::<lambda_b4b428a756e3b5d157dcc5597b762dc5> &openscheduleretrieve_ldlo::<lambda_b4b428a756e3b5d157dcc5597b762dc5>::operator =(const openscheduleretrieve_ldlo::<lambda_b4b428a756e3b5d157dcc5597b762dc5> &)': attempting to reference a deleted function
fileopen.cpp(1625): note: see declaration of 'openscheduleretrieve_ldlo::<lambda_b4b428a756e3b5d157dcc5597b762dc5>::operator ='
c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1378): note: while compiling class template member function 'std::unique_ptr<CP_CONVERT,openscheduleretrieve_ldlo::<lambda_b4b428a756e3b5d157dcc5597b762dc5>> &std::unique_ptr<CP_CONVERT,openscheduleretrieve_ldlo::<lambda_b4b428a756e3b5d157dcc5597b762dc5>>::operator =(std::unique_ptr<CP_CONVERT,openscheduleretrieve_ldlo::<lambda_b4b428a756e3b5d157dcc5597b762dc5>> &&) noexcept'
fileopen.cpp(1640): note: see reference to function template instantiation 'std::unique_ptr<CP_CONVERT,openscheduleretrieve_ldlo::<lambda_b4b428a756e3b5d157dcc5597b762dc5>> &std::unique_ptr<CP_CONVERT,openscheduleretrieve_ldlo::<lambda_b4b428a756e3b5d157dcc5597b762dc5>>::operator =(std::unique_ptr<CP_CONVERT,openscheduleretrieve_ldlo::<lambda_b4b428a756e3b5d157dcc5597b762dc5>> &&) noexcept' being compiled
fileopen.cpp(1626): note: see reference to class template instantiation 'std::unique_ptr<CP_CONVERT,openscheduleretrieve_ldlo::<lambda_b4b428a756e3b5d157dcc5597b762dc5>>' being compiled

1 Ответ

0 голосов
/ 25 апреля 2018

Лямбда не может быть назначена для копирования, поэтому вы не можете использовать это назначение здесь:

cpc = unique_ptr<CP_CONVERT, decltype( cpcdeleter )>( CreateCpConvert(), cpcdeleter );

Итак, вместо этого сделайте следующее:

auto cpcdeleter = []( CP_CONVERT * ptr ) { KillCpConvert( &ptr ); };
// Initialize your smart pointer with nullptr and the deleter needed
unique_ptr<CP_CONVERT, decltype( cpcdeleter )> cpc(nullptr, cpcdeleter);

...

// Then set the desired pointer
cpc.reset(CreateCpConvert());
...