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模板参数,对constmutable重载,编写相同函数:

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); }
posted @   zjh6  阅读(11)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示