Thread overview
opDispatch and UFCS
Jul 02, 2013
cal
Jul 02, 2013
Artur Skawina
Jul 03, 2013
cal
Jul 03, 2013
Kenji Hara
July 02, 2013
import std.conv, std.stdio, std.algorithm;

struct S {
    void opDispatch(string s, T...)(T t) if (s.startsWith("foo")) {
        writeln(s);
    }
}

void main() {
    S s;
    s.foo();
    auto p = s.to!string(); // Error: s.opDispatch!("to") isn't a template
}

Should the constraint on opDispatch allow the UFCS "to" call on S?
July 02, 2013
On 07/02/13 02:45, cal wrote:
> import std.conv, std.stdio, std.algorithm;
> 
> struct S {
>     void opDispatch(string s, T...)(T t) if (s.startsWith("foo")) {
>         writeln(s);
>     }
> }
> 
> void main() {
>     S s;
>     s.foo();
>     auto p = s.to!string(); // Error: s.opDispatch!("to") isn't a template
> }
> 
> Should the constraint on opDispatch allow the UFCS "to" call on S?

To avoid this kind of issues:

   struct S {
       template opDispatch(string s) if (s.startsWith("foo")) {
           void opDispatch(T...)(T t) {
               writeln(s);
           }
       }
   }

And, yes, the compiler should be able to handle your simpler case too, but currently doesn't (if there are several overloads then the transformation isn't necessarily this easy). I usually end up doing something like:

   struct S {
       static bool _disp(string s) {
          if (s.startsWith("foo"))
             return true;
          // ... other checks, AA lookups, introspection etc.
          return false;
       }
       template opDispatch(string s) if (_disp(s)) {
           void opDispatch(T...)(T t) {
               writeln(s);
           }
       }
   }

Dealing with the various frontend quirks can be fun.

artur
July 03, 2013
On Tuesday, 2 July 2013 at 11:04:20 UTC, Artur Skawina wrote:
> To avoid this kind of issues:
>
>    struct S {
>        template opDispatch(string s) if (s.startsWith("foo")) {
>            void opDispatch(T...)(T t) {
>                writeln(s);
>            }
>        }
>    }

That's a handy workaround, thank you.
July 03, 2013
On Tuesday, 2 July 2013 at 00:45:23 UTC, cal wrote:
> import std.conv, std.stdio, std.algorithm;
>
> struct S {
>     void opDispatch(string s, T...)(T t) if (s.startsWith("foo")) {
>         writeln(s);
>     }
> }
>
> void main() {
>     S s;
>     s.foo();
>     auto p = s.to!string(); // Error: s.opDispatch!("to") isn't a template
> }
>
> Should the constraint on opDispatch allow the UFCS "to" call on S?

That's a compiler bug.
http://d.puremagic.com/issues/show_bug.cgi?id=10526

Kenji Hara