On 07/03/18 17:11, Steven Schveighoffer wrote:
Well, you could do it with templates, but obviously that is less desirable:

void func2(Args...)(Args args) if(is(typeof(func(args)))) { return func(args); }

I never understood why anyone would use "is" for checking compilability when we have "__triats(compiles, func(args))".

With that aside, I would urge you not to use this test. It makes the error case worse. Check this out:

void func1(int a) {
}

void func2(Args...)(Args args) if( __traits(compiles, func1(args))) {
   func1(args);
}

void func3(Args...)(Args args) {
   func1(args);
}

void main() {
    long var;

    func2(var);
    func3(var);
}

Which error would you rather get? Calling func2 results in:
test.d(15): Error: template test.func2 cannot deduce function from argument types !()(long), candidates are: test.d(4): test.func2(Args...)(Args args) if (__traits(compiles, func1(args)))

Calling func3 results in:
test.d(9): Error: function test.func1(int a) is not callable using argument types (long) test.d(9): cannot pass argument _param_0 of type long to parameter int a
test.d(16): Error: template instance `test.func3!long` error instantiating

When calling func3, the compiler is telling you what's wrong (i.e. - you are passing a long to a function expecting a var). When calling func2, all you know is that there is some problem.


With that out of the way, I don't like generating proxy functions with "Args..." templates. They generate unneeded code bloat:

void main() {
  int var1;
  ubyte var2;
  byte var3;
  ushort var4;
  short var5;
  uint var6;

  // This generates 6 instantiations of the same function
  func2(var1);
  func2(var2);
  func2(var3);
  func2(var4);
  func2(var5);
  func2(var6);
}

If I could use Params, there would be only one instantiation.

Reply via email to