2013-02-12 52 views
4

在一个对象中,我有一个const-句柄数组给另一个特定类的一些对象。在一种方法中,我可能想要返回这个句柄之一作为inout-参数。这里作为一个简化的例子:inout参数 - 用另一个替换一个常量句柄

class A {} 

class B { 
    const(A) a[]; 
    this() { 
     a = [new A(), new A(), new A()]; 
    } 

    void assign_const(const(A)* value) const { 
     // *value = a[0]; // fails with: Error: cannot modify const expression *value 
    } 
} 
void main() { 
    const(A) a; 
    B b = new B(); 
    b.assign_const(&a); 
    assert(a == b.a[0]); // fails .. obviously 
} 

我不想删除原始数组中的常量。类B是指收集常数A -items的某种视图。我是来自C++的新手。 D-way中的const正确性是否已经搞乱了?我已经尝试了几种方法来使这个工作,但没有线索如何得到它的权利。

在没有“邪恶”铸造的情况下执行此查找的正确方法如何?

回答

5

丢掉const并修改元素在D中是未定义的行为。不要这样做。一旦出现const,它就是const。如果数组的元素是const,那么它不能被更改。因此,如果您有const(A)[],那么您可以将元素追加到数组中(因为它的元素是const,而不是数组本身),但不能更改数组中的任何元素。这与immutable一样。例如,stringimmutable(char)[]的别名,这就是为什么您可以附加到string,但不能更改其任何元素。

如果您想要一个const对象的数组,您可以在其中更改数组中的元素,则需要另一个间接级别。在结构的情况下,你可以使用指针:

const(S)*[] arr; 

但不会带班工作,因为如果C是一类,然后C*点,一类对象的引用,不是对象本身。对于课程,您需要做

Rebindable!(const C) arr; 

Rebindable在std.typecons中。

+0

抛弃const是我最后的选择,即使它是定义的行为。在此之前,我已经完全删除了常量。但是,在我找到一个可接受的解决方案之前,它已经过时了,可以使用Rebindable(..或者至少几天)。谢谢! – 2013-02-13 19:05:26

+1

如果你阅读一篇提及它的文章或对这样的问题的回答,那么你可能只会了解这类事情。但是由于D的类型系统的工作原理,你几乎不得不像''Rebindable''那样做一个'const'类,但是它的引用不是'const' - 类型系统根本没有任何差别的概念两者之间。 'Rebindable'很好地解决了这个问题,但是由于大多数人都很难理解为什么他们不能用语言本身来做,所以大多数人都会想到这种事情。 – 2013-02-13 23:45:14