How to change DList elements by means of foreach?
monarch_dodra
monarchdodra at gmail.com
Mon Sep 10 04:37:15 PDT 2012
On Monday, 10 September 2012 at 11:18:29 UTC, Alexandr Druzhinin
wrote:
> I have code:
>
> import std.container;
>
> int main() {
> // array
> int[] array = [0];
> foreach(ref value; array) {
> value += 50;
> assert(value == 50);
> }
>
> foreach(value; array) {
> assert(value == 50);
> }
>
> // double-linked list;
> DList!int dlist;
> dlist.insertFront(0);
> foreach(ref value; dlist) {
> value += 50;
> assert(value == 50);
> }
>
> foreach(value; dlist) {
> assert(value == 50); // Why do I have assertion failure here?
> }
>
> }
> How to change the value of elements of DList?
There is a know bug: foreach with ref does not currently work
these containers. The reason is that the container's front does
not actually expose a reference, but a value, and that is what is
being changed (the returned value).
There is no hope in sight to really *ever* make it work, because
"container.front += 5" can't be made to work if the returned
value is not a reference: Unlike indexes that define
opIndexOpAssign, there is no opFrontOpAssign.
What bothers *me* though is that the code compiles fine, biting
more than 1 user in the process.
Anyways... the workaround is* making an explicit loop, with
temporary object that is fed back into front, like this:
import std.container;
--------
void main()
{
// double-linked list;
DList!int dlist;
dlist.insertFront(0);
auto slice = dlist[]; //Extract a range manually
for( ; !slice.empty ; slice.popFront() )
{
auto value = slice.front; //Extract the value
value += 50; //Increment the value
slice.front() = value; //Feed back into the range*
}
foreach(value; dlist) {
assert(value == 50); //Now this works fine
}
}
--------
Well... this *would* work, but apparently, the implementation of
DList.Range doesn't define front(T value). This makes the Range
pretty much read-only. My guess is that this was an omission on
the part of the implementer. I will fix it so that it works.
More information about the Digitalmars-d-learn
mailing list