On Friday, 22 August 2014 at 21:22:39 UTC, Ali Çehreli wrote:
On 08/22/2014 01:45 PM, Yota wrote:
On Friday, 22 August 2014 at 20:42:49 UTC, Yota wrote:
Heya. I'm working on a simple units-of-measure
implementation in DMD
2.066.0, and it doesn't seem to like the signature of my '*'
operator
below. I'm afraid I don't understand what the error
description is
trying to tell me. Here's a reduced case:
Same results for this simpler signature.
public struct UnitDef(string unitString) {
auto opBinary(string op, string N)(UnitDef!N rhs)
if (op == "*") {
return UnitDef!(unitString ~ " " ~ N)();
}
}
I don't know the details about how it should work but the
following is a workaround:
public struct UnitDef(string unitString) {
alias US = unitString;
auto opBinary(string op, That)(That rhs)
if (is (That == UnitDef!(That.US)) &&
op == "*") {
return UnitDef!(unitString ~ " " ~ rhs.US)();
}
}
void main()
{
auto u = UnitDef!"hello"();
auto result = u * u;
pragma(msg, result.US);
}
I admit that the template constraint is strange because it
hopes that 'That' is an instance of UnitDef by reaching for its
.US member and then it also checks whether the type equals
that. :p
Admittedly, std.traits.isInstanceOf is the right tool to use
but both of the following worked!
auto opBinary(string op, That)(That rhs)
if (isInstanceOf!(UnitDef, That) &&
op == "*") {
return UnitDef!(unitString ~ " " ~ rhs.US)();
}
auto opBinary(string op, That)(That rhs)
if (isInstanceOf!(That, UnitDef) && // <-- REVERSED
op == "*") {
return UnitDef!(unitString ~ " " ~ rhs.US)();
}
Note the reversed template arguments of isInstanceOf. Still
works... Is that a bug?
Ali
Don't know either, but it was introduced in this PR, according to
Digger:
https://github.com/D-Programming-Language/dmd/pull/3536
which by its title shouldn't have this effect.
Note that the regression mentioned there by Vladimir was posted
there erroneously, the linked bug was actually caused by a
different PR.