vc2013与2015中的Lambda删除器
Lambda Deleter in VC 2013 vs 2015
我正在将一些旧代码从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
类型的参数调用。在你的例子中,pointer
是D*
。您的deleter不能用this调用,而是需要一个类型为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编译器,有些可能实际上能够编译上面的代码,但我没有把它们放在周围)
如果我没有错,问题是您将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编译?"
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 从链接列表c++中删除一个项目
- 如何使用lambda作为std::unique_ptr的删除器?
- Unique_ptr与 lambda 删除器
- 使用 lambda/std::function 删除拥有该函数的对象
- 是否可以使用 lambda 初始化变量(删除复制 ctor 时)
- 如果我在lambda中删除容纳lambda的对象,那会发生什么
- 如何避免多个删除程序 lambda
- 如何使用lambda和函数作为unique_ptr的自定义删除程序
- 使用 lambda 函数从 std::vector 中删除特定块
- 通过 lambda 删除矢量项
- C++ lambda 常量值引用在线程中删除
- C++ lambda 删除偶数
- unique_ptr<T> 用于数组专用化的 lambda 自定义删除器
- std::唯一指针和自定义lambda删除器错误
- 了解Lambda闭包类型如何删除默认构造函数
- vc2013与2015中的Lambda删除器