On Tuesday, 16 October 2018 at 02:13:21 UTC, Ali Çehreli wrote:
On 10/15/2018 01:36 PM, Márcio Martins wrote:
> Considering that the declaration is legal, and that the
template
> parameter deduction works when Args.length == 0, but stops
working when
> Args.length > 0.
For deduction to work, there must be function arguments. So,
just add Args to the function parameter list and all works:
import std.stdio;
void incx(T, Args...)(ref T t, Args) { // <-- Added Args
++t.x;
}
static struct Test(T) {
T x;
}
void main() {
Test!uint t;
t.incx();
t.incx!();
incx(t);
t.incx(1, 2, 3); // <-- Removed '!'
incx(t, 1, 2, 3);
writeln(t.x);
}
Ali
That's not exactly what I am trying to do.
Maybe I can share that - perhaps you guys know a better way that
circumvents these:
I am trying to have have a method that takes as arguments a
key-value pair,
where key is a string, and value is an alias to something
callable.
So I want to do things like:
t.on!(
"abc", {
writeln("abc");
},
"cde", {
writeln("cde");
}
);
I want to be able to hash the keys at compile time, and have the
callables not allocate at all.
The problem is that if `on` is a method on the aggregate `t`,
then I can't do this because i am passing local function literal
do non global template. I am not sure why this is a limitation, I
supposed I'd have to dig in the compiler code to find that out.
It certainly is an unexpected limitation, though.
So I tried to have the `on` be a global function, that has a
first argument of type T, a template parameter, and then takes a
compile-time alias sequence of the key-value pairs, as mentioned
earlier. This mostly works, except that it can't deduce the first
argument type, and forces me to write it up. The issue is that
it's a `voldemort` type, and even if wasn't it would be a quite
complex type to write, and I don't want my users to have to write
typeof() statements.
How can I best do this? I suppose I could do pass all of it as a
function argument instead, and have the first argument be
correctly deduced, but the performance characteristics will be
massively different, as I can no longer process the strings at
compile time, and the delegates passed as parameter are
guaranteed to allocate.
Help me understand if these are actual fundamental limitations,
bugs, or just the current implementation. It's quite frustrating
to invest a bunch of hours into a design that intuitively, IMO,
should work, just to find out it doesn't work due to an arbitrary
language limitation, and then spend time looking for an
alternative, and again, hit some intuitive language limitation.
If I understand the underlying limitation/implementation, I can
avoid these frustrations in the future.