D:为什么opIndex在std.container.Array类中不是const限定的?

时间:2014-08-18 17:38:25

标签: const d phobos

我最近想利用std.container.Array并继续创建一个带有getter成员函数的类,该函数从Array类返回一个值。我很快意识到我无法对我的getter进行const限定,因为opIndex是一个可变函数。

我尝试将源代码更改为const-qualify Array.opIndex,并且它构建得很好。但是,std.algorithm中的一些单元测试没有通过,抱怨Array.opIndex的返回值不是左值。

以下是Array.opIndex的代码:

ref T opIndex(size_t i)
{
    version (assert) if (!_data.refCountedStore.isInitialized) throw new RangeError();
    return _data._payload[i];
}

这里有什么我想念的吗?为什么它不符合常规?

1 个答案:

答案 0 :(得分:5)

使容器保持正确性存在许多问题,因为const使得它们无法在内部更改任何,这与C ++不同。只要您确保函数是逻辑mutable,就可以创建一些内容const。 IIRC,Array所做的操作理论上可以const,但不能归因于它的一些内部工作方式。如果因为这个原因,那些参与其中工作的人并没有做出任何事情const,即使其中有一部分可能会出现,也不会让我感到惊讶。

对于opIndex,我在该实现中看不到任何明显不可能是const的东西,而且它编译的事实暗示它可能有效。但是,如果你这样做,你需要重载它而不是简单地使那个特定的重载const,或者你将无法分配它 - 这可能是std.algorithm抱怨它的原因。所以,你需要像

这样的东西
ref T opIndex(size_t i) {...}
ref const(T) opIndex(size_t i) const {...}

这样它仍可以分配给它 - 例如arr[5] = "foo"; - 只要Array不是const。但是,由于Array的许多操作由于其实现方式的原因而不能const,因此我不知道它是如何有效地创建opIndex {{这样的函数1}},因为即使每个const成员函数都是const Array!T,您对const所做的事情也会非常有限。