unique_ptr custom storage type example?
Howard Hinnant explained that unique_ptr
can also use a custom storage type. He mentions as an example "shared memory".
He only gives the rough idea (which is fine for a quick intro). But can anyone complete his example for a "custom storage type" (be it shared memory or not)?
To support placing
unique_ptr
into shared memory, the custom deleter can contain a custom pointer type (typically not a real pointer in shared memory applications). One simply places a nested type called pointer which emulates pointer behavior within your deleter, publicly accessible:
template <class T>
class MyDeleter
{
public:
class pointer
{
public:
friend bool operator==(pointer x, poin开发者_如何转开发ter y);
friend bool operator!=(pointer x, pointer y);
// ...
};
void operator()(pointer p);
};
void test()
{
unique_ptr<int, MyDeleter<int> > p;
MyDeleter<int>::pointer p2 = p.get(); // A custom pointer type used for storage
}
I suspect that // ...
must be extended, and test()
will probably do some additional things in a real "custom storage type" example.
Can someone tell me where he/she
- has actually already used this customization,
- and in that context,
- which what customization code, (at
//...
probably) - and how client code uses it? (at
test()
probably)
You might be interested in boost::offset_ptr which served as the motivating use case for this customization point in unique_ptr
. offset_ptr
is a fully developed pointer type which could be installed into a custom deleter using a simple typedef. Its use case is to put unique_ptr
into shared memory.
20.7.1.2/3 tells us
The type unique_ptr<T, D>::pointer shall satisfy the requirements of NullablePointer (17.6.3.3).
According to 17.6.3.3, given a type P
, these requirements are:
P
is EqualityComparable, DefaultConstructible, CopyConstructible, CopyAssignable, and Destructible- Lvalues of
P
are swappable - Value-initializing an object of type P produces the null value of the type, and the null value shall be equivalent only to itself
- An object of type
P
can be contextually converted tobool
- An object of type
P
can be initialized with and assignednullptr
, and this produces the null value - An object of type
P
can be equality compared tonullptr
, and the comparison is true if and only if the object has the null value - None of the required operations may throw (but need no explicit
noexcept
orthrow()
)
Note specifically that operator*
and operator->
are not actually required. Also note that the builtin numeric types satisfy all the requirements except nullptr
initialization/assignment.
For example, the following type should fulfill all the requirements:
class handle {
int id;
public:
// default and nullptr constructors folded together
handle(std::nullptr_t = nullptr) : id(0) { }
explicit operator bool() { return l.id != 0; }
friend bool operator ==(handle l, handle r) { return l.id == r.id; }
friend bool operator !=(handle l, handle r) { return !(l == r); }
// default copy ctor and operator= are fine
// explicit nullptr assignment and comparison unneeded
// because of implicit nullptr constructor
// swappable requirement fulfilled by std::swap
}
精彩评论