【问题标题】:Non Member range functions非成员范围函数
【发布时间】:2010-10-05 23:25:29
【问题描述】:

我有一个要为其实现范围的类。我想以 phobos 库的方式实现这些功能,即在主类之外。

void popBack(T)(ref T[] a) if (!is(Unqual!T == char) && !is(Unqual!T == wchar))
{
    assert(a.length);
    a = a[0 .. $ - 1];
}

这是我的版本:

void popFront(T)(ref PersistentList!(T) a)
{
    a = a.next();   
}

当我尝试用 forech 编译这段代码时,我得到:

Error   1   Error: no property 'popFront' for type 'stmd.PersistentList!(int).PersistentList'   main.d  

我可以将成员代码移动到主类中,但是由于我正在修改输入“ref”值,所以我不能使用 popFront(),我真的需要 popFront(ref a)。

我做错了什么?

【问题讨论】:

    标签: d


    【解决方案1】:

    您想要做什么取决于 D 社区所称的统一函数调用语法。这是使用与成员函数相同的语法调用非成员函数的能力。很长一段时间以来,这一直只针对阵列实施,并且关于将其采用多远存在一些争论。已经决定应该为所有类型实现它,但编译器实现者 Walter Bright 还没有开始这样做,因为他一直在狂热地致力于 64 位支持。

    Andrei Alexandrescu 的著作“The D Programming Language”中描述了统一函数调用语法,该书被认为是 D2 的权威指南。它目前缺乏实现被认为是一个错误。这应该会在几个版本中修复。

    【讨论】:

    • 感谢您的评论。我的类是不可变的,所以我实际上不能在类本身中有一个 popFront 成员。但我确实创建了一个“PersistentListRange”子类,所以我可以做 foreach(i; lst.range) 并且效果很好。
    【解决方案2】:

    Phobos 仅在数组的结构/类之外实现范围函数。数组允许您在它们上调用函数,就好像它们是成员函数一样。所以,如果你有这个功能:

    int func(int[] arr)
    {
        return arr[0];
    }
    

    你可以这样称呼它

    auto arr = [1, 2, 3];
    auto val = arr.func();
    

    而不是

    auto val = func(arr);
    

    能够对所有类型执行此操作称为通用函数调用语法,但目前在 D 中这是不合法的,尽管它看起来可能会被添加。

    确实没有理由在范围类型之外声明范围函数,除非您希望与其他范围类型共享该实现,这通常是不可能的,因为内部实现必须处理如何容器类型维护其数据。因此,您不妨将它们作为您的范围类型的一部分。这就是 Phobos 在所有情况下所做的,除了数组,数组显然不能将它们作为其类型的一部分,并且必须利用它们的能力来调用函数,就好像它们是成员函数一样才能工作。

    【讨论】:

      猜你喜欢
      • 2013-04-20
      • 2010-11-22
      • 2011-06-22
      • 2018-03-30
      • 2011-07-03
      • 2014-07-29
      • 1970-01-01
      • 2016-07-14
      • 1970-01-01
      相关资源
      最近更新 更多