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) { }

Reply via email to