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