本文介绍了使用unique_ptr控制文件描述符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

理论上,我应该能够使用自定义指针类型和删除器,以便让 unique_ptr 管理不是指针的对象。我尝试了以下代码:

In theory, I should be able to use a custom pointer type and deleter in order to have unique_ptr manage an object that is not a pointer. I tried the following code:

#ifndef UNIQUE_FD_H
#define UNIQUE_FD_H

#include <memory>
#include <unistd.h>

struct unique_fd_deleter {
    typedef int pointer; // Internal type is a pointer

    void operator()( int fd )
    {
        close(fd);
    }
};

typedef std::unique_ptr<int, unique_fd_deleter> unique_fd;

#endif // UNIQUE_FD_H

这不起作用(gcc 4.7使用 -std = c ++ 11 参数)。它会响应以下错误:

This doesn't work (gcc 4.7 with the -std=c++11 parameter). It responds with the following errors:

In file included from /usr/include/c++/4.7/memory:86:0,
                 from test.cc:6:
/usr/include/c++/4.7/bits/unique_ptr.h: In instantiation of 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = int; _Dp = unique_fd_deleter]':
test.cc:22:55:   required from here
/usr/include/c++/4.7/bits/unique_ptr.h:172:2: error: invalid operands of types 'int' and 'std::nullptr_t' to binary 'operator!='

unique_ptr 的定义,我看到两个阻止它工作的问题。第一个似乎明显违反了标准,是 unique_ptr 的析构函数将指针(按照我的定义是int)与 nullptr 以查看其是否已初始化。这与通过布尔转换报告它的方式相反,布尔转换将它与 pointer() (未初始化的指针)进行比较。这是导致我看到错误的原因-整数与 nullptr 不具有可比性。

From delving into the definition of unique_ptr, I can see two problems that prevent it from working. The first, which seems in clear violation of the standard, is that the destructor for unique_ptr compares the "pointer" (which is, as per my definition, an int) to nullptr in order to see whether it is initialized or not. This is in contrast to the way it reports it through the boolean conversion, which is to compare it to "pointer()" (an uninitialized "pointer"). This is the cause of the errors I am seeing - an integer is not comparable to a nullptr.

第二个问题是我需要某种方法来告诉 unique_ptr 什么是未初始化的值。我希望以下代码段可以工作:

The second problem is that I need some way to tell unique_ptr what an uninitialized value is. I want the following snippet to work:

unique_fd fd( open(something...) );

if( !fd )
    throw errno_exception("Open failed");

要使其正常工作, unique_ptr 需要知道未初始化的值是-1,因为零是有效的文件描述符。

For that to work, unique_ptr needs to know that an "uninitialized value" is -1, as zero is a valid file descriptor.

这是 gcc ,还是我想在这里做根本无法完成的事情?

Is this a bug in gcc, or am I trying to do something here that simply cannot be done?

推荐答案

<$公开的类型c $ c> Deleter :: pointer 必须满足。其中最重要的是,该表达式必须合法: Deleter :: pointer p = nullptr; 。当然, nullptr 的定义很大程度上是因为它无法将 隐式转换为数字,因此这是行不通的。

The type exposed by the Deleter::pointer must satisfy the NullablePointer requirements. Chief among them, this expression must be legal: Deleter::pointer p = nullptr;. Of course, nullptr is pretty much defined by the fact that it cannot be implicitly converted to a number, thus this doesn't work.

您必须使用可以用 std :: nullptr_t 隐式构造的类型。像这样的东西:

You'll have to use a type which can be implicitly constructed with std::nullptr_t. Something like this:

struct file_desc
{
  file_desc(int fd) : _desc(fd) {}
  file_desc(std::nullptr_t) : _desc(-1) {}

  operator int() {return _desc;}

  bool operator ==(const file_desc &other) const {return _desc == other._desc;}
  bool operator !=(const file_desc &other) const {return _desc != other._desc;}
  bool operator ==(std::nullptr_t) const {return _desc == -1;}
  bool operator !=(std::nullptr_t) const {return _desc != -1;}

  int _desc;
};

您可以将其用作 Deleter :: pointer 类型。

这篇关于使用unique_ptr控制文件描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 04:05