Specialization Not Allowed for Deduced Parameter

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Aug 22 14:22:39 PDT 2014


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



More information about the Digitalmars-d-learn mailing list