Lambda Deleter in VC 2013 vs 2015

I am moving the old code from VC 2013 to 2015.

The simplified code below works fine in VC 2013, but doesn't work in 2015:

error C2664: 'void main::<lambda_da721648e605a5fd45c9a3fb8c3d06f6>::operator ()(main::D *&) const': cannot convert argument 1 from 'main::D *' to 'main::D *&'

I am not looking for a solution, but to explain what and why has changed.


Thank.

#include <memory>

int main()
{
  class D{};

  auto mydel = []( D*&p ) { delete p; p = 0; };

  std::unique_ptr< D, decltype(mydel) > up( new D );

  return 0;
}
+4
source share
2 answers

The type of the deleter must be called with a type argument pointer. In your case pointerthere is D*. Your failure cannot be triggered with this, but a type argument is required instead pointer&, so your code was poorly formed without the need for diagnostics.

, decltype(mydel) -. Lambda , . , :

std::unique_ptr< D, decltype(mydel) > up( new D );

, . :

std::unique_ptr< D, decltype(mydel) > up( new D, mydel );

.

- -2013, , , . MSVC2013 ++ 11.

, , , lvalue D*. , .


, , ++ 17 :

template<auto* pfunc>
struct stateless {
  template<class...Args>
  decltype(auto) operator()(Args&&...args)const {
    return std::invoke( pfunc, std::forward<Args>(args)... );
  }
};

int main() {
  class D{};

  auto mydel = []( D*p ) { delete p; };

  std::unique_ptr< D, stateless<+mydel> > up( new D );

  return 0;
}

MSVC2015 (, , ).

++ 17 ++ 17, ( ++ 1z, , .)

+4

, , up std:unique_ptr decltype(mydel), mydel.

std::unique_ptr< D, decltype(mydel) > up( new D, mydel );

cppreference,

, Deleter DefaultConstructible .

, , decltype(mydel) ( ?)

, , " VC 2015 ?" " VC 2013?"

+4

Source: https://habr.com/ru/post/1651438/


All Articles