I’m attempting to use std::unique_ptr in order to store the integer handle to some opaque objects. For this purpose, I have defined a custom deleter type which does typedef int pointer in order to override the raw pointer type to int instead of int*. This process is described in the last section of this site: http://asawicki.info/news_1494_unique_ptr_in_visual_c_2010.html
Here is some sample code to better illustrate what I’m attempting to do:
#include <memory>
#include <iostream>
static void close(int p)
{
std::cout << p << " has been deleted!" << std::endl;
}
struct handle_deleter
{
typedef int pointer;
void operator()(pointer p) { close(p); }
};
typedef std::unique_ptr< int, handle_deleter> unique_handle;
int main(int argc, char *argv[])
{
unique_handle handle(1);
return 0;
}
When I compile this code using GCC 4.7.2, I get the following error:
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/memory:86:0,
from unique_ptr_test.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/unique_ptr.h: In instantiation of ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = int; _Dp = handle_deleter]’:
unique_ptr_test.cpp:19:23: required from here
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/unique_ptr.h:172:2: error: invalid operands of types ‘int’ and ‘std::nullptr_t’ to binary ‘operator!=’
The code of the ~unique_ptr procedure reads as follows:
// Destructor.
~unique_ptr() noexcept
{
auto& __ptr = std::get<0>(_M_t);
if (__ptr != nullptr)
get_deleter()(__ptr);
__ptr = pointer();
}
According to me, the check against nullptr does not make sense since the raw pointer type is int (and not int* due to overriding it in HandleDeleter). Strangely enough, this code compiles with no error under GCC 4.6.1. Upon execution, the sample displays “1 has been deleted!” as expected.
I was wondering if there is any detail I’m overlooking or if it really is a bug within GCC’s STL implementation of unique_ptr.
Thanks,
PMJ
As I said in my comment, if the deleter type you pass has a nested
pointertypedef, it must fulfill the NullablePointer requirements:20.7.1.2 [unique.ptr.single] p3And
§17.6.3.3then lists all the requirements a type has to fulfill to be a NullablePointer. Certain semantics are listed in a table, where:Now, the simplest solution is to wrap your
intin a type that provides these semantics: