D's equivalent to C++'s std::move?
Matt Elkins via Digitalmars-d
digitalmars-d at puremagic.com
Wed Feb 3 18:01:51 PST 2016
On Thursday, 4 February 2016 at 01:26:55 UTC, Andrei Alexandrescu
wrote:
> On 02/03/2016 07:48 PM, Matt Elkins wrote:
>> This [apparent] lack of clean move semantics
>
> I very much wish there was a quick summary. I figure you've
> seen std.algorithm.move. What's missing? -- Andrei
Apologies, should have summarized. The issue I've been focused on
has been emulating C++'s std::unique_ptr for the purposes of
handling system resources which need explicit cleanup and which
are not copyable (or for which I want to disallow copying for
whatever reason). I want to still be able to move around my
handles to these resources, so long as the single-owner aspect is
maintained, and I want the wrapper to have minimal overhead (so
for example std.typecons.Unique is out, since it appears to
require the heap one way or another); in essence, I want
std::unique_ptr. It is quite possible that this is doable, but if
so the solution eludes me. Here is what I have so far:
[code]
import std.algorithm;
struct ResourceHandle(T, alias Deleter, T Default = T.init)
{
// Constructors/Destructor
this(T handle) {m_handle = handle;}
@disable this(this);
~this() {Deleter(m_handle);}
// Operators
@disable void opAssign(ref ResourceHandle lvalue);
ref ResourceHandle opAssign(ResourceHandle rvalue)
{swap(m_handle, rvalue.m_handle); return this;}
// Methods
@property inout(T) handle() inout {return m_handle;}
@property T handle(T handle) {Deleter(m_handle); m_handle =
handle; return m_handle;}
T release() {T result = m_handle; m_handle = Default; return
result;}
private:
T m_handle = Default;
}
[/code]
This seems to cover most of my bases, but I still can't do things
like this:
[code]
unittest
{
alias RH = ResourceHandle!(uint, (uint) {});
RH[] handles;
handles ~= RH(5); // Compile error: ResourceHandle is not
copyable because it is annotated with @disable
}
[/code]
One person on the forums suggested that this might be a compiler
bug (and referred me to a maybe-related bug report from 2011),
but it also might not. This seems to have similar practical
functionality to std::auto_ptr; works reasonably well for passing
around individual instances, but gets iffy when you want to put
it into a container. Incidentally, I -am- able to do this:
[code]
unittest
{
alias RH = ResourceHandle!(uint, (uint) {});
RH[] handles;
++handles.length;
handles[$ - 1] = RH(5);
}
[/code]
This has become my effective workaround, but it isn't terribly
clean and may not scale to other kinds of data structures (or it
may, haven't thought it through). Of course, I'm a D newbie and
could well just not be seeing the right way to define
ResourceHandle.
Sorry for all the C++ allusions to explain my intent. Then again,
I'm not terribly worried that the author of MC++D won't follow
them :).
More information about the Digitalmars-d
mailing list