我最近想利用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];
}
这里有什么我想念的吗?为什么它不符合常规?
答案 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
所做的事情也会非常有限。