On Friday, 31 July 2015 at 14:23:28 UTC, Atila Neves wrote:
On Friday, 31 July 2015 at 11:16:48 UTC, Biotronic wrote:
On Thursday, 30 July 2015 at 10:40:59 UTC, Atila Neves wrote:
[...]

Why are there two different things in the first place?

@satisfies!(myConcept, T) should test the constraints and give a sensible error message. This you use to indicate that type T implements myConcept.

Why can't another template use the very same concept information to check if a type implements the concept?

e.g.:

@satisfies!(myConcept, MyStruct)
struct MyStruct { /* ... */ }

void foo(T)(T t) if (check!(myConcept, T))
{ /* ... */ }

Because you want to:

1. Check your type and get sensible error messages
2. Use a constraint in function declarations

You can't have `@satisfies!(isInputRange, T)` give you an error message if it doesn't have access to the source code of the lambda that actually does the checking and you can't get error messages unless you force the compilation of code you _know_ won't compile.

It's ok for template constraints to be false without causing a compilation error; that's how we get compile-time template function resolution. When you're using something like `@satisfies` however, you want a compilation error and its message. That's why you need two things.

Atila

Notice however, that (again, in the PR), the "real" definition happens only once, in the check function. Then the constraint is always a trivial `enum MyConstraint = is(typeof(myCheckFunction));`. It's just a matter of moving the lambda away, giving it a name, and doing the weird `if(!__ctfe)` hack.

Atila

Reply via email to