如何接受 ref 和非 ref 值作为函数参数

How to accept both ref and non ref values as a function argument

我想在函数中获取任何类型的值 (r/lvalue),我还想确保该值不会在函数范围内发生突变,即使该值本身不是一个常量。

struct Tree(T) {
    T item;
    Tree!T* parent, left, right;

    this(T item) {
        this.item = item;
    }

    Tree!T* searchTree(const ref T item) {
        if (&this is null)
            return null;
        if (this.item == item)
            return &this;
        return (this.item < item) ? this.right.searchTree(item) : this.right.searchTree(item);
    }
}

unittest {
    auto text1 = "Hello", text2 = "World";

    auto tree2 = Tree!string(text1);
    assert(tree2.searchTree(text2) is null);
    assert(tree2.searchTree(text1) !is null);

}

这适用于 ref 参数,但是如果我为函数提供 int 文字,它会失败:

    auto tree1 = Tree!int(4);
    assert(tree1.searchTree(5) is null);
    assert(tree1.searchTree(4) !is null);

模板来拯救! D 有一个名为 auto ref 的功能,它会自动为 ref 和非 ref 参数生成重载。唯一的要求是函数必须是模板。

对于您的 searchTree 函数,这意味着它需要具有此签名:

    Tree!T* searchTree()(const auto ref T item)

通过这个简单的更改,您的代码应该可以编译并执行 The Right Thing™。

目前有一个 DMD 的实验性编译器开关允许这样做。 尝试将“-preview=rvaluerefparam”添加到您的编译器开关。