Problem with using std.math: abs and std.complex: abs at the same time
Simen Kjærås
simen.kjaras at gmail.com
Wed Sep 18 12:37:28 UTC 2019
On Wednesday, 18 September 2019 at 12:03:28 UTC, berni wrote:
> The following code doesn't compile:
>
>>import std.stdio;
>>
>>void main()
>>{
>> import std.complex: abs, complex;
>> import std.math: abs;
>>
>> auto a = complex(1.0,1.0);
>> auto b = 1.0;
>>
>> writeln(abs(a));
>> writeln(abs(b));
>>}
>
> The error message depends on the order of the two import
> statements. Seems like the second import is actually ignored.
import std.complex: abs, complex;
Is treated by the compiler as if you'd written something somewhat
like this:
static import std.complex;
alias abs = std.complex.abs;
alias complex = std.complex.complex;
When you add
import std.math: abs;
It's treated like:
static import std.math;
alias abs = std.math.abs;
In other words, we have two aliases with the same name inside a
function scope, and the compiler can't do that (try doing it
explicitly, as in the 'treated like' sections above - you'll get
a compilation error). This is related to why you can't have
overloaded nested functions:
unittest {
void fun() {}
void fun(int i) {} // declaration fun is already defined
}
How to resolve this, though? The simplest solution is to not use
selective imports:
import std.math;
import std.complex;
writeln(abs(complex(1.0,1.0)));
writeln(abs(1.0));
If you absolutely can't contaminate the scope with all the unused
symbols in std.math and std.complex, you *can* do this:
import std.stdio;
unittest {
import std.complex : complex;
static import std.math;
alias abs = MergeOverloads!(std.complex.abs, std.math.abs);
auto a = complex(1.0,1.0);
auto b = 1.0;
writeln(abs(a));
writeln(abs(b));
}
template MergeOverloads(T...) {
alias MergeOverloads = T[0];
static if (T.length > 1) {
alias MergeOverloads = MergeOverloads!(T[1..$]);
}
}
I would however label that a horrible hack.
FWIW, I've filed this issue:
https://issues.dlang.org/show_bug.cgi?id=20226
--
Simen
More information about the Digitalmars-d-learn
mailing list