Thread overview
struct constructor with rvalue param of same struct type
Jan 18, 2021
vitamin
Jan 19, 2021
Kyle Ingraham
Jan 19, 2021
vit
January 18, 2021
Hello, is it possible to create constructor which initialize 'ptr3' with const rvalue of same type?

struct Foo{}

static struct Ptr{
    void* impl;

    //ctor 1
    this(ref const typeof(this) x)pure nothrow @trusted @nogc{/*...*/}

    //ctor 2
    this(const Foo foo)pure nothrow @trusted @nogc{/*...*/}

    //ctor 3
    //Error: `struct Ptr` may not define both a rvalue constructor and a copy constructor
    //this(const typeof(this) ptr)pure nothrow @trusted @nogc{/*...*/}   //


}

void main(){

    const Ptr cptr;
    Ptr ptr1 = cptr;    //call ctor 1

    Ptr ptr2 = delegate const(Foo)(){   //call ctor 2
        return typeof(return).init;
    }();

    Ptr ptr3 = delegate const(Ptr)(){   //error
        return typeof(return).init;
    }();

}
January 19, 2021
I’m sorry that this isn’t a solution to your problem but your code caught my attention. What is your snippet supposed to do?


January 19, 2021
On Tuesday, 19 January 2021 at 06:49:06 UTC, Kyle Ingraham wrote:
> I’m sorry that this isn’t a solution to your problem but your code caught my attention. What is your snippet supposed to do?

This is more specific example:
https://run.dlang.io/is/W7rd2u

import std.traits : CopyTypeQualifiers;

struct Ptr(T)
if(is(T == struct)){
    private void* ptr;

    static if(is(T == const))
    this(ref const typeof(this) x)@trusted{
    	this.ptr = cast(typeof(this.ptr))x.ptr;
    }

    this(ref typeof(this) x)@safe{
    	this.ptr = x.ptr;
    }

    this(ref const typeof(this) x)const @safe{
    	this.ptr = x.ptr;
    }

    this(P : const Ptr!(U), U, this This)(auto ref P x)@trusted
    if(true
       	//&& !is(R == T)
        && is(CopyTypeQualifiers!(P, U)* : CopyTypeQualifiers!(This, T)*)
    ){
    	this.ptr = cast(typeof(this.ptr))x.ptr;
    }

}


struct Foo{
    //@disable this(this);
}

T get_rvalue(T)(){		
	return T.init;
}

void main()@safe{

    ///normal pointers
    {
        const(const(Foo)*) cpcf;	///const(Foo*)

        const(Foo*) cpf1 = cpcf;			        ///OK	
        const(Foo*) cpf2 = get_rvalue!(const(const(Foo)*));	///OK	

        const(Foo)* pcf1 = cpcf;				///OK	
        const(Foo)* pcf2 = const(const(Foo)*).init;		///OK
        const(Foo)* pcf3 = get_rvalue!(const(const(Foo)*));	///OK

    }

    //wrapped ptr:
    {
        const Ptr!(const Foo) cpcf;

        const Ptr!(Foo) cpf1 = cpcf;					///OK
        const Ptr!(Foo) cpf2 =  get_rvalue!(const Ptr!(const Foo));	///OK

        Ptr!(const Foo) pcf1 = cpcf;					///OK
        Ptr!(const Foo) pcf2 = const(Ptr!(const Foo)).init;		///OK
        Ptr!(const Foo) pcf3 = get_rvalue!(const Ptr!(const Foo));	///ERROR!
    }
}