On Friday, 10 February 2023 at 22:10:20 UTC, Ben Jones wrote:
I'm trying to write a range adaptor for linked list types. The range type seems to work OK, but my helper function to deduce the node type has a compiler error. My hunch is that `nextField` loses its association with T when I'm trying to pass it as a template parameter inside the helper method, but I can't use __traits(child) there to fix it.

Any idea how to fix the helper method?

Is this something that would be useful to add to std.range somewhere? Or is something like it already in Phobos?

Thanks

```
import std.stdio;
import std.range;

struct LinkedListAdaptor(alias nextField, T){
        T current;
    @safe:
        nothrow:

    this(T head){
        current = head;
    }

    bool empty() const {
        return current == null;
    }   

    T front() {
        return current;
    }

    void popFront() {
                current = __traits(child, current, nextField);
    }
}

auto linkedListAdaptor(alias nextField, T)(T head) if(is(T == U*, U)){
        return LinkedListAdaptor!(nextField, T)(head);

    //fails with:
//onlineapp.d(27): Error: symbol or expression expected as first argument of __traits `child` instead of `Node*` // return LinkedListAdaptor!(__traits(child, T, nextField), T)(head);
}

struct Node{
        int data;
    Node* next;
}

void main(){
        Node* head = new Node(10, new Node(20, null));

    auto rng1 = LinkedListAdaptor!(Node.next, Node*)(head);
    auto rng = linkedListAdaptor!(Node.next)(head);
    foreach(const x; rng){
        writeln(x.data);
    }
}
```

This fails with:

Error: need `this` for `linkedListAdaptor` of type `pure nothrow @nogc @safe LinkedListAdaptor!(next, Node*)(Node* head)`

The problem is that Node.next is not, and cannot be `static`. Thus, there is no way for you to pass it as an alias template parameter, and this should be considered a compiler bug that this doesn't error out.

Reply via email to