问题描述
理论上,我应该能够使用自定义指针类型和删除器,以便让 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 $ c中的错误吗? $ c>,还是我想在这里做根本无法完成的事情?
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控制文件描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!