I am moving some old code from VC 2013 to 2015.
The simplified code below works fine in VC 2013, but fails in 2015 with:
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 for an explanation on what and why changed.
Thank you.
#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;
}
The type of deleter must be callable with an argument of type pointer
. In your case pointer
is D*
. Your deleter is not callable with this, but instead requires an argument of type pointer&
, so your code was ill-formed with no diagnostic required.
In addition, decltype(mydel)
is a lambda object type. Lambda objects have no default constructor, even stateless ones. Your unique pointer creating code:
std::unique_ptr< D, decltype(mydel) > up( new D );
is thus ill-formed. The correct verson would be:
std::unique_ptr< D, decltype(mydel) > up( new D, mydel );
This is annoying.
Odds are 2013's lambda had a zero argument constructor lying around, in violation of the standard. MSVC2013 was only nominally a C++11 compiler.
In addition, it probably only passed in lvalue D*
types. It is permitted to do this, but it is not required to do it by the standard.
While this is not the focus of your question, I will note we can clean this up in C++17 as follows:
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;
}
but MSVC2015 doesn't support this (maybe if you requested the latest standard in a later update it might).
C++17 code not tested on a C++17 compiler, as none actually exist yet (There are some C++1z compilers, and some might actually be able to compile the above, but I don't have them lying around.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With