digitalmars.D - How is std.traits.isInstanceOf supposed to work?
- Tommi (25/25) Nov 10 2013 The documentation says:
- Dicebot (5/13) Nov 10 2013 I'd say "works as expected". 'alias this` is not equivalent to
- Tommi (6/8) Nov 10 2013 According to TDPL, 'alias this' makes the aliasing type a
- TheFlyingFiddle (36/36) Nov 10 2013 The docs might be a little unclear about this. The template
- Jonathan M Davis (4/8) Nov 10 2013 Which implies that it really should have been called isInstantiationOf a...
- Tommi (20/22) Nov 10 2013 But in this example of mine:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (16/36) Nov 12 2013 The compiler magically deduces T as int:
- Tommi (2/2) Nov 11 2013 Filed a bug report:
The documentation says: template isInstanceOf(alias S, T) --------------------------- Returns true if T is an instance of the template S. But, is isInstanceOf supposed to return true if T is a subtype of an instance of the template S ? (but is not an instance of the template S). Currently it does return true if T is a struct, and doesn't if it's a class: import std.traits; struct SuperSt(T, int size) {} struct SubSt { SuperSt!(short, 4) _super; alias _super this; } class SuperCl(T, U) {} class SubCl : SuperCl!(int, char) {} void main() { static assert(isInstanceOf!(SuperSt, SubSt)); static assert(!isInstanceOf!(SuperCl, SubCl)); }
Nov 10 2013
On Sunday, 10 November 2013 at 23:22:01 UTC, Tommi wrote:The documentation says: template isInstanceOf(alias S, T) --------------------------- Returns true if T is an instance of the template S. But, is isInstanceOf supposed to return true if T is a subtype of an instance of the template S ? (but is not an instance of the template S). Currently it does return true if T is a struct, and doesn't if it's a class:I'd say "works as expected". 'alias this` is not equivalent to inheritance, it allows to type to completely act as another. And `isInstanceOf` checks for strict matching. It will work with classes if `alias this` is used there.
Nov 10 2013
On Sunday, 10 November 2013 at 23:34:08 UTC, Dicebot wrote:I'd say "works as expected". 'alias this` is not equivalent to inheritance, it allows to type to completely act as another.According to TDPL, 'alias this' makes the aliasing type a 'subtype' of the aliased type. If type X is a subtype of type Y, it doesn't mean that X can completely act as Y. It means that objects of type X can completely act as objects of type Y. Which is not the same thing.
Nov 10 2013
The docs might be a little unclear about this. The template isInstanceOf checks to see if the second parameter is a template instantiation of the first parameter. It does not have anything to do with inheritance. Like so: struct S(T) { T t; } struct S2(T) { T t; } import std.traits; unittest { alias inst = S!(int); alias inst2 = S2!(string); //S!(int) is an instantiation of S static assert(isInstanceOf!(S, inst)); //S2!(string) is not an instantiation of S static assert(!isInstanceOf!(S, inst2)); } If you would like to see if something is derived from something or to see if a struct is convertible to another struct use the is keyword. Like so: struct S3 { S!(int) s; alias s this; } class C { } class D : C { } unittest { //S3 is convertible to S!(int) static assert(is(S3 : S!(int))); //D is convertible (derived from) C static assert(is(D : C)); }
Nov 10 2013
On Monday, November 11, 2013 00:43:17 TheFlyingFiddle wrote:The docs might be a little unclear about this. The template isInstanceOf checks to see if the second parameter is a template instantiation of the first parameter. It does not have anything to do with inheritance.Which implies that it really should have been called isInstantiationOf and not isInstanceOf. - Jonathan M Davis
Nov 10 2013
On Sunday, 10 November 2013 at 23:43:21 UTC, TheFlyingFiddle wrote:The template isInstanceOf checks to see if the second parameter is a template instantiation of the first parameter.But in this example of mine: isInstanceOf!(SuperSt, SubSt) ...the second parameter is not a template instantiation of the first parameter, yet isInstanceOf evaluates to true. I think what this all boils down to is that this is a compiler-bug: struct A(T) {} struct B { A!int _a; alias _a this; } void main() { static assert(!is(B == A!int)); // OK static assert(is(B == A!T, T)); // BUG (shouldn't compile) }
Nov 10 2013
On 11/10/2013 05:03 PM, Tommi wrote:On Sunday, 10 November 2013 at 23:43:21 UTC, TheFlyingFiddle wrote:The compiler magically deduces T as int: struct A(T) {} struct B { A!int _a; alias _a this; } void main() { static if (is(B == A!T, T)) { pragma(msg, T); // prints int } } AliThe template isInstanceOf checks to see if the second parameter is a template instantiation of the first parameter.But in this example of mine: isInstanceOf!(SuperSt, SubSt) ...the second parameter is not a template instantiation of the first parameter, yet isInstanceOf evaluates to true. I think what this all boils down to is that this is a compiler-bug: struct A(T) {} struct B { A!int _a; alias _a this; } void main() { static assert(!is(B == A!int)); // OK static assert(is(B == A!T, T)); // BUG (shouldn't compile) }
Nov 12 2013
Filed a bug report: https://d.puremagic.com/issues/show_bug.cgi?id=11499
Nov 11 2013