On Saturday, 17 May 2014 at 01:53:46 UTC, Steven Schveighoffer
wrote:
A possible solution:
template interface isInputRange(T, E) { .. No change in
implementation .. }
void myTemplateFunction(T : isInputRange!int)(T t)
{
}
would basically change this into the equivalent of today's
constraints. however, given that the template parameter is
coupled with the constraint more directly, a better error
message could be created, e.g. "Type MyNonRangeType does not
satisfy template interface isInputRange!int."
I like this, but may I suggest a slightly different approach: to
parallel structures, classes, interfaces, etc., concepts could be
defined as nouns. This avoids the need to define dummy type
parameters ("T", above) and construct lvalues from them. It also
sidesteps the awkward "is-typeof-lambda" idiom:
static interface InputRange(E)
{
// This code must compile for any InputRange!E.
bool empty = this.empty;
E front = this.front;
this.popFront();
}
void f1(T : InputRange!int)(T) { }
void f2(E, T : InputRange!E)(T) { }
This parallels the existing (declarative) notion of template
specialization. With this scheme, one could also overload
concepts:
static interface InputRange
{ static assert(is(typeof(this) < InputRange!E, E)); }
// For the common case in which we don't need to name
// the element type:
void f3(T : InputRange)(T) { }