Weird template instantiation problem

Arafel via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jun 12 08:44:36 PDT 2017


On 06/12/2017 05:31 PM, Arafel wrote:
> Hi,
> 
> I've found a strange problem, and I'm not sure if it's a bug. To give a 
> bit of background, I'm implementing a multi-threaded producer-consumer 
> where the next work item to be picked depends not only on the "waiting 
> queue", but also on what else is being run (and potentially where) at 
> the same moment, so things like "sort"'ing the queue won't probably 
> work, because I don't think you use a delegate as a predicate for "sort" 
> (that's what I think it would be needed to get the extra context 
> information).
> 
> The idea here is that the "chooser" function returns the *index* of the 
> work item to be picked.
> 
> So, the reduced problem looks like this (I've removed the extra 
> information about the running jobs to make the example simpler):
> 
> ```
> enum defaultChooser(T) = function size_t(T[] queue) {
>      return 0;
> };
> 
> struct S(T, size_t function(T[]) chooser = defaultChooser!T) {
> }
> 
> void main() {
>      S!int s;
> }
> ```
> 
> this fails and I get this:
> 
>> Error: template instance S!int does not match template declaration 
>> S(T, ulong function(T[]) chooser = defaultChooser!T)
> 
> If instead of returning the index the actual item is returned, it works!
> 
> ```
> enum defaultChooser(T) = function T(T[] queue) {
>      return queue[0];
> };
> 
> struct S(T, T function(T[]) chooser = defaultChooser!T) {
> }
> 
> void main() {
>      S!int s;
> }
> ```
> 
> As you can see, the only change is the type the function returns, but I 
> don't see how it should make any difference.
> 
> Also, changing from "enum" to "static immutable", or even removing the 
> "enum" and directly embedding the function literal doesn't seem to make 
> any difference.
> 
> Any ideas on what might be going on??

Even more strange:

```
enum defaultChooser(T) = function size_t(T[] queue) {
	return 0;
};

static assert (is (typeof(defaultChooser!int) == size_t function(int[] 
queue) pure nothrow @nogc @safe));

struct S(T, size_t function(T[] queue) pure nothrow @nogc @safe chooser) {
}

void main() {
	S!(int, defaultChooser!int) s;
}
```

The static assert passes (tried with the wrong values), yet I get this 
error message:

> Error: template instance S!(int, function ulong(int[] queue) => 0LU) does not match template declaration S(T, ulong function(T[] queue) pure nothrow @nogc @safe chooser) 

Am I missing something fundamental? But then, why does it work if I 
change the return type in the template parameter?


More information about the Digitalmars-d-learn mailing list