I've been experimenting with code that uses std.functional : binaryFun and unaryFun, but I have found that using these methods makes it impossible to add function attributes like @safe, @nogc, pure, and nothrow, because no guarantee can be made about the functions created via a stream. For example, if you expect a comparator function like "a == b", someone can pass in "a.data--" instead.

That being said, I started trying out using strongly typed and attributed template parameters instead, relying on lambdas to keep the syntax for the user short. But when I tried this, I found that the very existence of templates with different parameter values causes a collision during compilation.

The following code snippet demonstrates the error:

```
import std.stdio;

final class BTree(
    ValueT, KeyT = ValueT,
const(KeyT) function(ValueT) @safe @nogc nothrow pure KeyF = (a) => a) {
        
        KeyT getKey(ValueT val) {
                return KeyF(val);
        }
}

void main()
{
auto btree1 = new BTree!(char); // Removing this line eliminates the error.
    auto btree2 = new BTree!(int);
}
```

The error is:
```
onlineapp.d(8): Error: function literal `__lambda6(char a)` is not callable using argument types `(int)` onlineapp.d(8): cannot pass argument `val` of type `int` to parameter `char a` onlineapp.d(15): Error: template instance `onlineapp.BTree!(int, int, function (char a) => a)` error instantiating
```

Is this an error in the compiler or in my own understanding of the D language?

Reply via email to