【问题标题】:Iteration over const collections in D迭代 D 中的 const 集合
【发布时间】:2016-01-08 14:44:00
【问题描述】:

在 C++ (STL) 中,我们定义了 const 和 non-const 方法以及两种迭代器,用于在集合上进行迭代:

class Container
{
    public:
    iterator begin();
    const_iterator begin() const;
};

我们如何将这种技术扩展到 D?我的第一次尝试:

class Container(T) {
    class Range {
        ref T front();
        // implementation
    }

    class ConstRange {
        T front() const;
        // implementation
    }

    Range all() {
        return new Range(/**/);
    }

    ConstRange all() const {
        return new ConstRange(/**/);
    }
}

unittest {
    alias list = List!int;
    const list L = new list;
    writeln(L.all());
}

但是失败了。我有一个错误: Error: nested type List.List!int.List.Range should have the same or weaker constancy as enclosing type const(List!int)

怎么了?

【问题讨论】:

  • 常量迭代器?这甚至是 D 中的东西吗?
  • @sigod,不,但麻烦不在其中)D 中没有“const 范围”,但对 const 容器的迭代必须正常工作,并且方法 front 不应返回 ref T。即使它不是“D-way”
  • std.array.d makes the range external(请记住 private 如果在文件/模块级别而不是类级别)

标签: iterator constants d


【解决方案1】:

解决方案是让你的范围存在于容器之外,但仍然引用它。如果范围在容器内,则受传递 const 规则的约束,但如果在容器外,则可以在可变范围内保留 const 引用。如果在同一个文件中定义它们,范围仍然可以看到容器的私有成员。

观察:

class Container(T) {
        private T[] contents;

        this(T[] contents) {
                this.contents = contents;
        }

        RangeOver!(Container!T, T) getRange() {
                return RangeOver!(Container!T, T)(this);
        }
        RangeOver!(const(Container!T), const(T)) getRange() const {
                return RangeOver!(const(Container!T), const(T))(this);
        }
}

struct RangeOver(Container, T) {
        Container container;
        size_t iterationPosition;
        this(Container container) {
                this.container = container;
                this.iterationPosition = 0;
        }

        ref T front() {
                return container.contents[iterationPosition];
        }

        bool empty() {
                return iterationPosition == container.contents.length;
        }

        void popFront() {
                iterationPosition++;
        }
}


void main() {
        import std.stdio;

        // mutable iteration
        {
                writeln("about to mutate...");
                auto container = new Container!int([1,2,3]);
                foreach(ref item; container.getRange()) {
                        writeln(item);
                        item += 5;
                }
                writeln("mutation done");
                // changes seen
                foreach(item; container.getRange())
                        writeln(item);
        }

        // const iteration
        {
                writeln("consting it up y0");
                const container = new Container!int([1,2,3]);
                // allowed
                foreach(item; container.getRange())
                        writeln(item);
        }
}

【讨论】:

  • 非常感谢。我忘了在 D 中 const 是可传递的。
猜你喜欢
  • 1970-01-01
  • 2015-08-17
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
  • 2017-03-10
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多