July 25

It seems one can’t have one in a struct together with a copy constructor, but what is it? When is it called? What is it for?

July 25
On Thursday, July 25, 2024 4:48:06 PM MDT Quirin Schroll via Digitalmars-d- learn wrote:
> It seems one can’t have one in a struct together with a copy constructor, but what is it? When is it called? What is it for?

An rvalue constructor is a constructor that takes the same type as the struct that it's in, but it takes it as an rvalue (whereas a copy constructor takes it as an lvalue). So, if you have

struct MyType
{
    this(MyType rhs)
    {
        ...
    }
}

then you can do stuff like MyType(getMyType()) where getMyType returns a MyType, whereas if you don't have such a constructor, you can't. This is particularly useful in generic code. For instance, if you have an algebraic type that takes a whole bunch of types, you can do something like

    this(T)(T rhs)
    {
        ...
    }

and then you can happily call MyType(getMyType()) where getMyType() returns
a MyType.

However, without that rvalue constructor, then MyType(getMyType()) can't be
done. So, if MyType has a copy constructor, you're forced to check for
MyType with such a templated constructor, e.g.

    this(T)(T rhs)
        if(!is(immutable T == immutable MyType))
    {
        ...
    }

and you need to create a wrapper function to be able to generically construct a MyType, e.g.

    MyType make(T)(T rhs)
    {
        static if(is(immutable T == immutable MyType))
            return rhs;
        else
            return MyType(rhs);
    }

Of course, for most code, you really don't need to be able to construct a struct from its own type, so in many cases, you really don't need an rvalue constructor, but when you do need it, the fact that copy constructors don't allow them is pretty annoying.

With the current DIP proposal for move constructors, an rvalue constructor would become a move constructor, though since it's not necessarily obvious that that's what it is, and such constructors already exist as normal constructors, there are some objections to making such a change. But of course, we'll have to see what ultimately happens with that.

- Jonathan M Davis