On 08/22/2014 02:22 PM, Ali Çehreli wrote:

> Admittedly, std.traits.isInstanceOf is the right tool to use

Answering myself: Yes, it is.

> but both of
> the following worked!

I figured that out.

>      auto opBinary(string op, That)(That rhs)
>          if (isInstanceOf!(UnitDef, That) &&

Note that UnitDef above means the template instance UnitDef!unitString. (There is such a shortcut in D and C++.)

Since I've been using the same type in my test code, UnitDef!unitString and That were the same type. (Hm. Does that mean that one is the instance of the other? Will have to test that separately.)

So, the correct check should use std.traits.TemplateOf first:

    auto opBinary(string op, That)(That rhs)
        if (isInstanceOf!(TemplateOf!UnitDef, That) &&
            op == "*") {
        return UnitDef!(unitString ~ " " ~ rhs.US)();
    }

Now, that's correct and allows different instances:

import std.traits;

public struct UnitDef(string unitString) {
    alias US = unitString;

    auto opBinary(string op, That)(That rhs)
        if (isInstanceOf!(TemplateOf!UnitDef, That) &&
            op == "*") {
            pragma(msg, typeof(this));
            pragma(msg, That);
        return UnitDef!(unitString ~ " " ~ rhs.US)();
    }
}

void main()
{
    auto u = UnitDef!"hello"();
    auto v = UnitDef!"world"();
    auto result = u * v;
    pragma(msg, result.US);
}

Ali

Reply via email to