gpt4 book ai didi

c++ - VC 2013 与 2015 中的 Lambda 删除器

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:22:15 27 4
gpt4 key购买 nike

我正在将一些旧代码从 VC 2013 移至 2015。

下面的简化代码在 VC 2013 中运行良好,但在 2015 年失败:

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

我不是在寻找解决方案,而是在寻找更改内容和更改原因的解释。


谢谢。

#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;
}

最佳答案

删除器的类型必须可以用 pointer 类型的参数调用。在您的例子中,pointerD*。你的删除器不能用这个调用,而是需要一个 pointer& 类型的参数,所以你的代码格式错误,不需要诊断。

此外,decltype(mydel) 是一个 lambda 对象类型。 Lambda 对象没有默认构造函数,即使是无状态的。您的独特指针创建代码:

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

因此是病式的。正确的版本是:

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

这很烦人。

很可能 2013 年的 lambda 有一个零参数构造函数,这违反了标准。 MSVC2013 只是名义上的 C++11 编译器。

此外,它可能只传入了左值 D* 类型。允许这样做,但标准不要求这样做。


虽然这不是您问题的重点,但我会注意到我们可以在 C++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 不支持此功能(如果您在以后的更新中请求最新标准,它可能会支持)。

C++17 代码未在 C++17 编译器上测试,因为实际上还不存在(有一些 C++1z 编译器,有些实际上可以编译上述代码,但我没有他们躺在周围。)

关于c++ - VC 2013 与 2015 中的 Lambda 删除器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38980630/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com