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