Subject: Re: [boost] [RFC] unique_val (handles, IDs, descriptors...)
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2018-02-15 10:18:34
2018-02-14 22:18 GMT+01:00 Miguel Ojeda via Boost <boost_at_[hidden]>:
> Hi all,
> While working on a medium-sized project, I had to wrap quite some
> handles, IDs, descriptors, etc. into RAII classes. Somehow, writing
> those and making them movable seemed more verbose than needed. I
> searched in the STL and Boost for something already implemented, but
> nothing seemed to come up. I decided to write my own prototype to see
> whether I was missing something important; but actually using it in my
> project felt quite natural and simple.
> At this point, I asked for a second opinion from a well-known expert
> (thanks Scott!) and he agreed that it seemed like a reasonable idea
> but, of course, he would also be surprised if others haven't come up
> with something similar. So I polished it up a bit and uploaded it to:
> Below you have the introduction inlined .
> If you have the time, please take a look (specially to the Rationale)
> and let me know your comments. The code itself is very short and
> If you already have this class/template in Boost somewhere that I
> missed, please let me know! Otherwise, if you think this could be
> interesting to put into Boost in some existing library (not sure
> which) or as a new tiny library, I would be glad to make the effort to
> expand it, clean it up, etc.
So, it is my understanding that the difference between an `int` and an
`unique_val<int>` is that the latter is not copyable (and whoever keeps it
as member is not copyable), and moving from it guarantees that a certain
default value will be assigned to it. Right?
If I got that right, I have two remarks.
1. In your example:
Foo() : id_(CreateFoo(/* ... */))
if (not id_)
throw std::runtime_error("CreateFoo() failed");
Foo(Foo&&) = default;
Foo& operator=(Foo&&) = default;
`id_` is private (should be of no interest to the users). `Foo` is indeed
non-copyable, but it has not been explicitly declared to the users: it has
only been inferred from the private member (implementation detail). I would
still expect that the class has copy operations explicitly deleted so that
I know it is by design rather than by the current choice of private members.
Your type indeed prevents accidental copying. But at least the example
encourages a bad practice of not declaring the interface of your class
2. Next thing I have to do after defining my `unique_value<>` type is to
write a RAII wrapper for the resource. So, as others mentioned` maybe I
would prefer a tool for doing the latter rather than only a movable ID.
There is a proposal for adding this into the Standard Library:
And also a reference implementation:
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk