Operator overloading

Jonathan M Davis jmdavisProg at gmx.com
Fri Apr 20 10:31:20 PDT 2012


On Friday, April 20, 2012 15:37:57 Xan wrote:
> Thanks, Jonathan. I suppose with 'if' (dynamic), it generates
> Exception if we call with other operator than '*', isn't?

Exception? No. You get a compilation error. You should read

http://dlang.org/template.html#Constraint
http://dlang.org/version.html#staticif

Template constraints are used to indicate what will and won't compile with a 
template and can be used to overload templates.

For instance, with

auto opBinary(string op)(MyType mt)
 if(op == "+" || op == "-")
{...}

auto opBinary(string op)(MyType mt)
 if(op == "*" || op == "/")
{...}

the first function would work with + and -, whereas the second would work with 
* and /, and those are the only overloads for opBinary, and you tried to 
compile with another binary operator, you'd get a compilation error. It's 
quite typical to do stuff like

auto MyType(string op)(MyType mt)
 if(op == "+" || op == "-' || op == "*" || op == "/")
{
 return MyType(mixin("this.value " ~ op ~ " mt.value"));
}

You use static if when you want a section of code to be different based on some 
condition. So, you could do something like

auto MyType(string op)(MyType mt)
 if(op == "+" || op == "-' || op == "*" || op == "/")
{
 static if(op == "/")
 enforce(mt.value != 0, "Error: Division by zero!");
 
 return MyType(mixin("this.value " ~ op ~ " mt.value"));
}

The problem with your example

 Algorisme!(U,V) opBinary(string op)(Algorisme!(U,V) alg) {
 static if (op=="*") return new Algorisme!(U,V)("composició", 
this.versio+alg.versio, this.funcio);
 }

what happens when you try and compile with an operator other than *. When it's 
*, you end up with a function looking like

 Algorisme!(U,V) opBinary(string op)(Algorisme!(U,V) alg) {
 return new Algorisme!(U,V)("composició", 
this.versio+alg.versio, this.funcio);
 }

but when it's anything else, you get a function looking like

 Algorisme!(U,V) opBinary(string op)(Algorisme!(U,V) alg) {
 }

It has no return value and won't compile, giving you an error about returning 
void or something similar.

If at all possible, you should always have a template constraint on a template 
which restricts it to arguments which will work with that template. You can 
then further specialize sections of it using static if, but if you use static 
if only, then you get nasty compilation errors when you misuse the template. 
Also, you can't overload templates based on static if, so if you need to have 
mulitple overloads of a template, you _need_ to use template constraints.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list