d中复制构造器与构造器

原文
vit:为什么这段代码无法编译?

struct Foo(T){
    this(Rhs, this This)(scope Rhs rhs){
    }

    this(ref scope typeof(this) rhs){
    }
}


struct Bar{
	Foo!int foo;
}

void main(){
}
//错误:分段错误(已转储核心)

RazvanN:
问题是编译器会尝试为Bar生成大致如下所示的inout复制构造器:

this(ref scope inout(Bar) p) inout
{
    this.foo = p;
}

降级理念是是尽量调用Foo对象的复制构造器.问题是复制构造器(__ctor)构造器符号相同,因此降级this.foo=pfoo.__ctor(p).
因为实例和参数都是inout,不能调用Foo的复制构造器,因而调用模板构造器.生成this(scope inout(Foo))inout;样的构造器模板实例.它是右值构造器.不是有效代码;如果这样:

struct Foo(T){
    //this(Rhs, this This)(scope Rhs rhs){}
    this(scope inout(Foo!int) rhs) inout {}
    this(ref scope typeof(this) rhs){
    }
}

将收到不能同时定义右值复制构造器的错误消息.但,由于是模板化构造器,在实例化构造器前,编译器不能发出错误.有2个可能修复方法:
(1)重命名复制构造器__cpCtor,这样不会与普通构造器重载集冲突
(2)实例化模板构造器时,可检查是否是右值构造器,并在存在复制构造器时发出错误.
实现复制构造器时,我认为(1)更好,但d作者坚持要他们有相同名称.所以,(2)是要走的路.

Tejas:那为什么我的修改成功了?

struct Foo(T){
    this(Rhs, this This)(scope Rhs rhs){
    }

    this(scope Foo!(T)* rhs){ 
    //用 Foo!T替换typeof(this),用指针替换引用.
    //保留typeof(this),依然工作
    }
}


struct Bar{
	Foo!int foo;
}

void main(){
	import std.stdio:writeln;
	
	Bar bar = Bar();
	auto BAR = new Bar();
	writeln(bar, "\t", BAR, "\t", *BAR);
}

RazvanN:
是的,要通过传递ref参数来显式定义复制构造器.因为你期望显式指针,编译器不按复制构造器对待,因此不会为Bar生成复制构造器.
在此
vit:现在如下工作了:

struct Foo(T){
    this(Rhs, this This)(auto ref scope Rhs rhs)
    if(__traits(isRef, rhs) == false){
    }

    this(ref scope typeof(this) rhs){
    }
}


struct Bar{
	Foo!int foo;
}

void main(){
}
上一篇:[噼昂!]我被卷飞了


下一篇:Python 自定义一个正无穷大的整数