of "Conditional Implementation" vs "Assertive Input Validation"

Jacob Carlborg doob at me.com
Tue Jul 24 05:50:07 PDT 2012

On 2012-07-24 10:37, xenon325 wrote:

> I remember this was discussed recently and Don Clugston suggested
> something like this:
> if there is no match for:
>      void foo(T)(T t) if( !conditionA!T ){}
>      void foo(T)(T t) if( conditionA!T && conditionB!T ){}
> the error will be:
> template foo does not match any function template, constraints values are:
>      conditionA: true
>      conditionB: false
> (note that `conditionA` is listed only once)
> And given who Don is, I'm pretty sure he have an idea how to implement
> this.

That will be just a little better. The problem is it will leak 
implementation details. For this to be useful you really need to create 
a template for every condition:

template isFoo (T)
     enum isFoo = is(T == Foo);

void foo (T) (T t) if (isFoo!(T));

If you just do it like this:

void foo (T) (T t) if (is(T == Foo));

Then it will leak the "raw" condition. With my approach the constraint 
will have a name which should result in a lot better error messages.

Think of it like this. You have a function, "foo", taking an interface 
parameter, "Foo":

interface Foo
     void a ();
     void b ();
     void c ();

void foo (Foo f);

You then call the function with an object that does _not_ implement the 
function, then you get a proper easily understandable error message:

foo(new Object);

Error: Object doesn't implement Foo

What would you think if the error message look like this instead:

Error: Object doesn't have the methods:
     void a ();
     void b ();
     void c ();

Now imagine that with a bunch of conditions instead.

void foo (T) (T t) if (__traits(compiles, { T t; t.foo; t.bar; }) || 
is(T : Foo));

Error: template foo does not match any function template, constraints 
values are:
      __traits(compiles, { T t; t.foo; t.bar }) false
      is(T : Foo) false

/Jacob Carlborg

More information about the Digitalmars-d mailing list