is(Type:Type) fails to evaluate to true

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Mon Oct 8 16:10:10 PDT 2007


silverclaw wrote:
> I picked up the Matrix class I abandoned some months ago and updated it to the latest DMD (2.022). However, on the opMulAssign the following check fails where it should pass:
> 
> const Matrix!(Type) opMul(T)(const T multiplier)
> {
> 	static if (is(T:Matrix)) //multiplication by a Matrix
> 	{ (....) }
> 	else //multiplication by a scalar
> 	{ (....) }
> }

I assume this is a member of your Matrix template?

> It used to work on some other compiler version. So, on the main() I made the following code:
> 
> (static) if (is(Matrix:Matrix)) writefln("true");
> else writefln("false");
> 
> always evaluates to false (prints "false") with or without the "static". As you may have noticed, it is a template class:
> 
> public class Matrix(Type)
> 
> As I said, it used to work, I'm going to try to find out with which DMD. Any suggestions?

Are you sure it used to work like this?
Notice that inside the Matrix template definition, 'Matrix' refers to 
the current instantiation of the template, not the template itself.
For a matrix multiplication, you may not want either of those behaviors.
The current instantiation would only allow matrices of the exact same 
type (not other, compatible types. consider Matrix!(int) * 
Matrix!(short) for example).
If Matrix referred to the template itself it would simply not work 
(causing the is() to return false) since a template is not a class (even 
though an *instance* of that template may be).

One simple method to detect whether a type is an instance of Matrix 
would be to make all template instances derive from a common 
(non-templated) base class (or interface), and test for that. (Using a 
class would be most efficient, since interfaces require an extra vtable 
pointer)
Note that you don't even need to declare any members for the base 
class/interface since you know that any class derived from it should 
have certain members, and your code uses the actual type T of that 
class. It's just a tag to tell you "This thing is a Matrix".

So then the declaration would start with e.g.
---
class MatrixBase {}

public class Matrix(Type) : MatrixBase {
---
and the test would be something like
---
     static if (is(T:MatrixBase)) //multiplication by a Matrix
---


More information about the Digitalmars-d-learn mailing list