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?