【问题标题】:I have no idea what this C++ one-liner does我不知道这个 C++ one-liner 做了什么
【发布时间】:2019-12-07 21:50:23
【问题描述】:

我在 Github 上发现了一个内部非常奇怪的单行函数:

std::unique_ptr<std::remove_pointer<HANDLE>::type, void(*)(HANDLE)> hDevice{h, [](HANDLE handle){CloseHandle(handle);}};

作为一个从未接触过 c++ 的人,我不知道它的作用。

我想,这里有两个嵌套匿名函数以某种方式与 std::remove_pointerstd::unique_ptr 调用相关联。我在内部函数中看到一个 WinAPI CloseHandle 调用,并假设我应该从它开始我的分析。我不能说更多。

这里可能有两个嵌套的泛型。

花括号和“大于”符号的使用对我来说也很奇怪。它打破了我所知道的所有典型案例。

请帮助了解这个集团。我不知道如何用谷歌搜索它的部分。

【问题讨论】:

标签: c++


【解决方案1】:

首先让我们对其进行格式化,使其可读:

std::unique_ptr<std::remove_pointer<HANDLE>::type, void(*)(HANDLE)> hDevice{
   h,
   [](HANDLE handle) { CloseHandle(handle); }
};

这是一个名为hDevice 的对象的声明,用两个参数初始化。一个是h,另一个是lambda function。我们会回到那个。

对象的类型是std::unique_ptr&lt;std::remove_pointer&lt;HANDLE&gt;::type, void(*)(HANDLE)&gt;&lt;&gt; 表示这是一个模板的实例化。有问题的模板是std::unique_ptr,一个用于内存管理的标准组件,一个智能指针。

两件事:

  • std::unique_ptr&lt;T&gt; 是一种指向 T 类型对象的指针。
  • std::unique_ptr&lt;T, D&gt; 是指向 T 类型对象的指针类型,带有 D 类型的自定义“删除器”;我们会回到这一点。

您的Tstd::remove_pointer&lt;HANDLE&gt;::type。 Windows 为我们提供了类型别名HANDLE,它是一种混淆指针类型。该表达式为我们提供了 HANDLE 指向的事物的类型(并且以一种很好的通用方式进行,无需对结果进行硬编码;Microsoft 可以更改 HANDLE 的定义,并且只要它仍然是一个指针,这仍然有效)。

您的Dvoid(*)(HANDLE)。那是函数指针的类型,一个指向函数的指针,它采用HANDLE 并返回void。哦,看起来很眼熟:它是一种函数指针类型,与您作为构造函数参数提供的 lambda 兼容。

那是因为 lambda 自定义删除器。它告诉unique_ptr 当智能指针超出范围时该做什么。通常这只是一个不错的delete,但这里我们有一个 Windows API 函数 (CloseHandle) 来调用,它为我们进行清理。这可能涉及delete 和其他内容,也可能仅涉及其他内容。重点是这是关闭HANDLE 的正确方法。

总的来说,这个声明创建了一个std::unique_ptr,它获得了HANDLE h 的所有权,并确保当std::unique_ptr 超出范围时调用CloseHandle(h) .

tl;dr:这是一种将RAII 添加到 Windows 句柄的方法。

【讨论】:

    猜你喜欢
    • 2011-07-14
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    相关资源
    最近更新 更多