March 26, 2005
Hello fellow D programmers and enthusiasts.

I am wondering if you might be able to help me with a problem.  I thought it would be a good idea to write a bunch of complex math routines to complement D's native complex types.

To begin, I wrote a quick function to compute complex z to the real power n (z^n
= r^n(cos(n*theta) + sin(n*theta)i)).  It's definition is:
creal pow(creal z, real n){...code...}.

The function works fine, I've even used it to draw some fractals.  The problem
arises when I want to call regular pow as defined in std.math which has two
definitions:
real pow(real, real) and
real pow(real, uint)

DMD compiles my code to use my pow function, even though I'm not passing any complex variables or assigning the return value to a complex variable.  The only way I've gotten DMD to call the correct function is to explicitly call std.math.pow.

Is there any solution to this aside from just renaming my function to cpow? Thank you for your help.

- Peter


March 26, 2005
> DMD compiles my code to use my pow function, even though I'm not passing
> any
> complex variables or assigning the return value to a complex variable.
> The only
> way I've gotten DMD to call the correct function is to explicitly call
> std.math.pow.
>
> Is there any solution to this aside from just renaming my function to cpow?

You've stumbled across D's overload resolution behavior across scopes. The
way it works is that first the scope containing the symbol name is found and
then overloading is done within that scope. So if the user wants to have a
module import both std.math and your cmath then they will either have to:
1) explicitly say which pow they want or
2) define aliases to bring the different pow's into the module scope
import std.math;
import cmath;
alias std.math.pow pow;
alias cmath.pow pow;

If you expect user to be using both std.math and your math then prefixing
might be the way to go.
Another option is you yourself can import std.math and define the aliases"
module cmath;
import std.math;
alias std.math.pow pow;
cdouble pow(cdouble,...){...}
but the downside there is that you'd then have to define versions that take
double, float, idouble etc to avoid ambiguous overload resolution (once you
start overloading implicit conversions go out the window generally)