| Thread overview | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
November 10, 2013 How is std.traits.isInstanceOf supposed to work? | ||||
|---|---|---|---|---|
| ||||
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));
}
| ||||
November 10, 2013 Re: How is std.traits.isInstanceOf supposed to work? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Tommi | 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.
| |||
November 10, 2013 Re: How is std.traits.isInstanceOf supposed to work? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Tommi | 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));
}
| |||
November 11, 2013 Re: How is std.traits.isInstanceOf supposed to work? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | 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
| |||
November 11, 2013 Re: How is std.traits.isInstanceOf supposed to work? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | 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)
}
| |||
November 11, 2013 Re: How is std.traits.isInstanceOf supposed to work? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dicebot | 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.
| |||
November 11, 2013 Re: How is std.traits.isInstanceOf supposed to work? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Tommi | Filed a bug report: https://d.puremagic.com/issues/show_bug.cgi?id=11499 | |||
November 12, 2013 Re: How is std.traits.isInstanceOf supposed to work? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Tommi | On 11/10/2013 05:03 PM, Tommi wrote:
> 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)
> }
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
}
}
Ali
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply