opDispatch and operator overloads

Steven Schveighoffer schveiguy at yahoo.com
Tue May 21 12:53:46 PDT 2013


On Tue, 21 May 2013 15:36:31 -0400, Timon Gehr <timon.gehr at gmx.ch> wrote:

> On 05/21/2013 05:31 PM, Steven Schveighoffer wrote:
>> On Mon, 20 May 2013 11:15:32 -0400, John Colvin
>> <john.loughran.colvin at gmail.com> wrote:
>>
>>> struct S {
>>>     auto opDispatch(string s)(A i){}
>>> }
>>>
>>> struct A {}
>>>
>>> void main() {
>>>     S s;
>>>     A a;
>>>     s + a; //Error: incompatible types for ((s) + (a)): 'S' and 'A'
>>> }
>>>
>>> It would be really nice if opDispatch could catch missing operator
>>> overloads.
>>
>> Not sure this can work.  opDispatch takes a string identifying the
>> function name, but opBinary is a template that ALSO needs a string.
>>
>> I suppose the string parameter to opDispatch could be the explicit
>> instantiation:
>>
>> s.opDispatch!"opBinary!\"+\""(a)
>>
>
> It is parsed in a different way as is assumed here, the AST after  
> opDispatch rewrite looks like this:
>
> (s.opDispatch!"opBinary")!"+"(a);

OK, so the result of opDispatch needs to be a template, not a function.   
OK, I can follow that

>> but that would seem extremely difficult to handle, you'd kind of need a
>> parser to deal with it.
>>
>
> This handles your case using opDispatch:
>
> import std.stdio,std.conv,std.algorithm,std.array;
>
> string commaSep(T...)(T args){
>      string r="";
>      foreach(a;args) r~=a.to!string~",";
>      return r[0..$-!!$];
> }
>
> struct S{
>      template opDispatch(string name){
>          template opDispatch(T...){
>              auto opDispatch(S...)(S args){
>  writeln(this,".",name,"!"~T.stringof~"(",commaSep(args),")");
>              }
>          }
>      }
> }
>
> void main(){
>      S s;
>      s.opBinary!"+"(2); // ok
>      // s.foo(); // error. should IMO be fixed.
>      s.foo!()(); // ok
>      s.bar!([1,2,3],int)("123"); // ok
> }
>
>
>> what is the problem with just defining opBinary to catch missing
>> operator overloads?
>>
>
> It is more boilerplate.  
> https://github.com/D-Programming-Language/phobos/blob/bcf7dd9bd268956754bf1a034728bef29619e858/std/typecons.d#L2654

This pretty much makes my point.  I have no idea what your 3-level  
opDispatch does.  The proxy type, while verbose, I can understand.

Yes, lots of boilerplate.  If anything, though, that's an argument to fix  
how operator overloading works.

At the end of the day, it's going to be less boilerplate for the  
std.typecons.Proxy that one has to mixin.  User code will look the same.

-Steve


More information about the Digitalmars-d mailing list