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.

Reply via email to