【问题标题】:How to accept both ref and non ref values as a function argument如何接受 ref 和非 ref 值作为函数参数
【发布时间】:2020-06-03 00:56:59
【问题描述】:

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

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);

【问题讨论】:

    标签: constants d ref rvalue


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 说“auto 只能用作模板函数参数的自动引用的一部分”似乎失败了 (run.dlang.io/is/hRPMtn)
    • ()(const auto ref T item) 中的空括号很重要——它们将函数标记为模板,而没有它们它只是一个普通函数。再试一次。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2014-10-01
      • 2015-10-02
      • 2018-11-11
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      相关资源
      最近更新 更多