d是否可从单个方法返回可变和常区间
原文
我设法制作了可保存常性的通用getParent()函数.对inout也可以.
但可对所有父输入区间生产函数这样做吗?
在常区间实现中,内部存储是非常的,只是在front()属性中隐式转换为常.
它提供了我需要的保护,但可更漂亮吗?
import std;
class A{
inout(A) getParent() inout{ return null; }
this(A p){
}
}
class B : A{
A parent;
override inout(A) getParent() inout{ return parent; }
auto allParents(){
struct ParentRange{
A act;
@property bool empty() const{ return act is null; }
@property A front() { return act; }
void popFront(){ act = act.getParent; }
}
return ParentRange(getParent);
}
auto allParents()const {
struct ConstParentRange{
A act;
@property bool empty() const{ return act is null; }
@property const(A) front() inout { return act; }
void popFront(){ act = act.getParent; }
}
return ConstParentRange(cast()getParent);
}
this(A p){
super(p);
parent = p;
}
}
auto test(inout A a, void delegate(inout A) fun){
auto p = a.getParent;
fun(p);
}
void main()
{
auto a = new A(null);
auto b = new B(a);
const c = b;
writeln(c.getParent);
c.test((in d){ writeln(d); });
writeln;
c.allParents.each!writeln;
writeln;
b.allParents.each!writeln;
}
是否可结合上面的两个实现?如下根据typeof(this)来选择类型.
import std;
class A{
inout(A) getParent() inout{ return null; }
void nonConstMemberFunc() {}
void constMemberFunc() const {}
this(A p){
}
}
class B : A{
A parent;
override inout(A) getParent() inout{ return parent; }
struct ConstOrMutable(T) {
//别名不严格要求'static if'可定义'act'
static if (is (T == const)) {
alias X = const(A);
} else {
alias X = A;
}
X act;
@property auto empty() const { return act is null; }
@property auto front() { return act; }
void popFront() { act = act.getParent; }
}
auto allParents() inout {
return ConstOrMutable!(typeof(this))(cast()getParent());
}
this(A p){
super(p);
parent = p;
}
}
auto test(inout A a, void delegate(inout A) fun){
auto p = a.getParent;
fun(p);
}
void main()
{
auto a = new A(null);
auto b = new B(a);
assert( __traits(compiles, b.constMemberFunc()));
assert( __traits(compiles, b.nonConstMemberFunc()));
const c = b;
assert( __traits(compiles, c.constMemberFunc()));
assert(!__traits(compiles, c.nonConstMemberFunc()));
}
技术上讲,你代码是合理折衷方案.两个版本有足够不同,结合起来可能意义不大.
可用this模板参数,对const和mutable重载,编写相同函数:
import std.stdio;
class C
{
void foo(this This)(string s) {writefln("for %s this is %s", s, This.stringof); }
}
void main()
{
auto c = new C;
c.foo("mutable");
const c2 = c;
c2.foo("const");
}
但因为不可赋值常类实例,通用代码中会包含static if.
std.typecons.Rebindable可能有用.
在"inout"之前,"this This"是做到该点的唯一方法.它真的很有用.还有is(T==const).
我用默认初化器按模板参数传递isConst.它只需要返回前的区间的静如.
后代类的父类是可选的(重载getParent)
allParents,thisAndAllParents:在父前,可选地枚举this.
还可过滤allParents!CustomContainer类类型,支持常量.比先前回调访问版本更好.
我相信最终会生成编译器可很好优化的当循环.(与递归或回调不同)
inout(Container) getParent() inout { return null; }
void setParent(Container p){}
auto thisAndAllParents(Base : Cell = Cell, bool thisToo = true, bool isConst=is(typeof(this)==const))() inout{
struct ParentRange{
private Cell act;
private void skip(){
static if(is(Base==Cell)) {}
else while(!empty && (cast(Base)act is null)) popFront;
}
this(const Cell a){ act = cast()a; skip; }
@property bool empty() const{ return act is null; }
void popFront(){ act = act.getParent; skip; }
auto front() {
static if(isConst) return cast(const Base)act;
else return cast(Base)act;
}
}
return ParentRange(thisToo ? this : getParent);
}
auto allParents(Base : Cell = Container)() inout{ return thisAndAllParents!(Base, false); }
浙公网安备 33010602011771号