type of if statement used for operator overloading?
Jonathan M Davis
jmdavisProg at gmx.com
Tue Feb 5 22:37:04 PST 2013
On Wednesday, February 06, 2013 07:24:10 Jeremy DeHaan wrote:
> I've seen operator overloading done 3 different ways. In the
> examples I provide they all compile and work as far as I can
> tell. Is there any major difference between using a static if vs
> a regular if, or any situation that one would be better than the
> other?
>
>
> struct Something1
> {
> Something1 opUnary(string s)()
> {
> if (s == "-")
> {
> return stuff;
> }
> }
>
> }
Don't do this. You want to be generating different functions for different
overloaded operators. This just introduces extra runtime overhead. It also
fails to deal with all of the possible values of s.
> struct Something2
> {
> Something2 opUnary(string s)()
> {
> static if (s == "-")
> {
> return stuff;
> }
> }
>
> }
This is better but again fails to deal with all of the possible values of s.
You'll get a nasty error message if a different value gets passed in.
> Also, I realize that if I wanted to overload just a single
> operator and that was all, I could do:
>
> struct Something3
> {
> Something3 opUnary(string s)()
> if (s == "-")
> {
>
> return stuff;
>
> }
>
> }
>
> But I am more curious about the first two.
The last one is by far the best, because it protects against values for s that
you don't intend to overload for. You can with the second example if you
really want to and have multiple operators that you want to overload with the
same function, but you still need a template constraint to protect against
values that you don't intend to handle. Pretty much _every_ template that you
write should have a template constraint on it.
And in many cases, overloaded operators should just use string mixins. For
instance, core.time.Duration does this:
Duration opBinary(string op, D)(D rhs) @safe const pure nothrow
if((op == "+" || op == "-") &&
(is(_Unqual!D == Duration) ||
is(_Unqual!D == TickDuration)))
{
static if(is(_Unqual!D == Duration))
return Duration(mixin("_hnsecs " ~ op ~ " rhs._hnsecs"));
else if(is(_Unqual!D == TickDuration))
return Duration(mixin("_hnsecs " ~ op ~ " rhs.hnsecs"));
}
It uses static ifs to differentiate between Duration and TickDuration (since
they require different code), but the code doesn't differentiate between the
operators. Rather, it just mixes in the string, and it'll do the right thing
in both cases. The template constraint already protects against operators that
it doesn't actually overload.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list