On Thu, 23 Feb 2012 08:15:52 +0100, Martin Nowak <d...@dawgfoto.de> wrote:

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

A working solution was to let move return a proxy which defers the move
until it gets implicitly converted into an rvalue.

auto move(T)(ref T src)
{
    /* Non-instantiable non-copyable proxy to forward moves.
     */
    static struct Proxy(T)
    {
        static import std.algorithm;

        ~this()
        {
            if (_ptr !is null)
            {
                typeid(T).destroy(_ptr);
                _ptr = null;
            }
        }

        /* Triggers move on implicit conversion.
         */
        @property T get()
        {
            auto p = _ptr; _ptr = null;
            return std.algorithm.move(*p);
        }

        alias get this;

    private:
        @disable this();
        @disable this(this);

        this(T *p) { _ptr = p; }
        T* _ptr;
    }

    return Proxy!T(&src);
}

The proxy can be forwarded, but has the downside that one can escape references.

auto foo()
{
    int val;
    return move(val); // ouch
}

void bar()
{
    {
        int a;
        auto m = move(a);
    }
    int b = m; // ouch
}

Reply via email to