std::unique_ptr 自定义删除器似乎需要一个指针参数——有没有可以采用非指针变量的替代方法?

问题描述 投票:0回答:0

我最近被介绍到这种使用 std::unique_ptr 来实现“通用”RAII 机制的机制:

// main.cpp

#include <memory>
#include <sys/fcntl.h>
#include <unistd.h>

#define RAII_CAT(x) raii ## x

#define RAII_CAT2(x) RAII_CAT(x)

#define RAII_FD(X) \
    std::unique_ptr<int, void(*)(int*)> RAII_CAT2(__LINE__){X, [](int* x){ if (-1 != *x) { close(*x); }}}

int main(int argc, char* argv[]) {
  {
    int fd = open("foo.txt", O_RDONLY);
    RAII_FD(&fd);
  }

end:
  return 0;
}

在上面的代码中,RAII_FD 宏创建一个 std::unique_ptr 对象,其自定义删除器接受一个 int*——指向文件描述符的指针——并在文件描述符上调用 close()

我非常喜欢这种机制,但我有点抱怨自定义删除器需要一个 pointer 作为它的论点:从美学上讲,它感觉有点不尽如人意。
例如。在上面的代码中,自定义删除器是 int close(int) 的一个薄包装器——因此,如果自定义删除器可以采用 int 而不是 int* 就好了……在这种情况下,可能不需要包装器函数根本:也许可以提供指向 int close(int) 本身的函数指针。

即尝试了以下变体,尝试注册一个带有签名 void func(int) 而不是 void func(int*):

的自定义删除器
// main.cpp

#include <memory>
#include <sys/fcntl.h>
#include <unistd.h>

#define RAII_CAT(x) raii ## x

#define RAII_CAT2(x) RAII_CAT(x)

#define RAII_FD(X) \
    std::unique_ptr<int, void(*)(int)> RAII_CAT2(__LINE__){X, [](int x){ if (-1 != x) { close(x); }}}

int main(int argc, char* argv[]) {
  {
    int fd = open("foo.txt", O_RDONLY);
    RAII_FD(fd);
  }

end:
  return 0;
}

...编译错误是 stl 错误的呕吐物,我可能不会 100% 理解,但我认为要点是在各种模板扩展中存在 int*/int 不匹配。

是否有另一种类似的机制可以通过自定义删除器实现“通用”RAII 机制,其参数不一定需要是指针?

我愿意学习所有可能的解决方案,但在我的目标环境中实际可用的解决方案必须是 C++11 和非 Boost。最可取的是在 STL 原生对象上使用一些类似的“薄包装器”。

c++ stl unique-ptr raii
© www.soinside.com 2019 - 2024. All rights reserved.