Rvalue forwarding

Martin Nowak dawg at dawgfoto.de
Wed Feb 22 23:15:52 PST 2012


Is it possible to forward rvalues through variadic templates?
Having to "move" the value for every layer is suboptimal.
What am I doing wrong?

----------

import std.algorithm : move;

void foo(Unique!Handle uniq)
{
     auto val = uniq.extract;
     assert(val._fd == 1);
     val.close();
}

void foo(Unique!Handle uniq, string)
{
     auto val = uniq.extract;
     assert(val._fd == 1);
     val.close();
}

version (none)
{
     void bar(Args...)(Args args)
     {
         foo(move(args)); // cannot forward variadic arguments ???
     }
}
else
{
     void bar(A0)(A0 a0)
     {
         foo(move(a0));
     }

     void bar(A0, A1)(A0 a0, A1 a1)
     {
         foo(move(a0), move(a1));
     }
}

void main()
{
     Unique!Handle uniq;

     uniq = Unique!Handle(Handle(1));
     assert(uniq._obj._fd == 1);
     bar(move(uniq));
     assert(uniq._obj._fd == 0);
     uniq = Unique!Handle(Handle(1));
     assert(uniq._obj._fd == 1);
     bar(move(uniq), "other arg");
     assert(uniq._obj._fd == 0);
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

struct Handle
{
     this(int fd)
     {
         _fd = fd;
         assert(_fd);
     }

     void close()
     {
         _fd = 0;
     }

     ~this()
     {
         assert(!_fd);
     }

     int _fd;
}

struct Unique(T)
{
     this()(auto ref T val) if(!__traits(isRef, val))
     {
         move(val, _obj);
     }

     this()(auto ref Unique!T val) if(!__traits(isRef, val))
     {
         move(val._obj, _obj);
     }

     @disable this(this);

     void opAssign(Unique val)
     {
         move(val._obj, _obj);
     }

     @property T extract()
     {
         return move(_obj);
     }

private:
     T _obj;
}


More information about the Digitalmars-d mailing list