原文
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=p
为foo.__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(){
}