d无法生成复制构造器
原文
Digger
抱怨是复制构造器
的原因.
是的;它适合postblit
和按值复制
的构造器
,但不适合按引用
使用的复制构造器
.
化简用例:
struct Array
{
void opSliceAssign(Foo) {}
void opSliceAssign(Foo, size_t, size_t) {}
}
struct Foo {
Bar _bar;
}
struct Bar {
version (Bug)
this(ref Bar) { }
else
this(Bar) { }
}
void main()
{
Foo foo;
Array arr;
arr[] = foo;
}
基本
问题是,编译器看到有个定义了复制构造器
的字段
的构时,会生成如下形式的inout
复制构造器:
this(ref inout(T)) inout;
此时,它为Foo
创建如下复制构造器
:
this(ref inout(Foo) p) inout
{
this._bar = p._bar;
}
因为,
this._bar = p._bar
//重写为
this._bar.__copyCtor(p._bar)
因为不能用'(ref inout(Bar))inout'
参数类型调用'this(ref Bar)'
,生成的复制构造器
编译失败.因此按disable
注解它.
我实现复制
构造器时,最初提出
该方案时考虑
到,如果想升级postblits
为复制构造器
,那么可简单地替换
this(this)
//为
this(ref inout typeof(this) p) inout
这样,postblit
的生成机制会类似,且代码不会受到影响
.
然而,我想了又想,想到了更好生成
方案.它可消除该错误
且代码可编译,但是Walter
反对,所以现在被inout
构造器卡住了.
所以,总结一下,按目前语言规则
,该错误
是正确的.
修复方法
是用'inout'
如下注解Bar
的复制构造器:
this(ref inout(Bar)) inout
这使代码编译.但我同意可改进
该错误的.
如果结构包含间接
指针,这就不管用了,如,添加可变
指针到Bar
.
谢谢你的解释,这真需要一些工作
.目前,如下都失败了
struct Bar { this(ref Bar) {} }
struct Bar { this(const ref Bar) {} }
因为编译器为
struct Foo { Bar _bar; }
生成inout
复制构造器
如果失败
了,不应完全禁止
它,而应该试回退
到可变或常
的复制构造器
,并传播字段
的限制
.
原文
如果字段
定义了复制构造器
,则无法生成
并调用
复制构造器.
这对使用引用计数
的类型是相当令人沮丧
的.
void main() {
Depender a, b;
b = a;
}
struct Dependency {
this(ref Dependency other) {
this.tupleof = other.tupleof;
}
~this() {
}
}
struct Depender {
Dependency dependency;
}
//生成复制构造器失败,因此不可复制它的实例
从依赖项
中移除
析构器会使其编译.
添加按引用取Depender
的opAssign
也可工作:
void opAssign(ref Depender other) {
this.tupleof = other.tupleof;
}
生成Depender
的复制构造器
时,如下:
this(ref inout Depender src) inout
{
this.dependency = dependency;
}
但是,
this.dependency = dependency;
//重写为,不能调用的
this.dependency.copyCtor(dependency);
因为它是可变
的,而用inout
对象,所以不能调用它.因此,按disable
标记复制构造器
.
Dependency
的析构器使编译器生成带:
ref Dependency opAssign(Dependency src)
签名的opAssign
.该赋值
操作符使(包含Dependency
的)Depender
也定义了按值
接收参数的opAssign
.在此调用生成(和禁止)
的复制构造器
.
修复20876
以正确
生成更准确的复制构造器
会修复此问题.
另一个
方法是停止基于复制构造器和析构器
生成赋值操作符
.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现