What's the use of 'typeof','typeid','__traits','is' ?

Steven Schveighoffer schveiguy at gmail.com
Sun Aug 24 14:40:36 UTC 2025


On Sunday, 24 August 2025 at 03:13:38 UTC, David T. Oxygen wrote:

> The `is_int_or_float()` function has also simplified.
> Then I need to use another function to get the type of the 
> result of `is_int_or_float()`, so I may write another piece of 
> code like:
> ```d
> import std.stdio;
> string inputing="3.14";
> MyReal result=is_int_or_float(inputing);
> if(/*?????*/){
>     writeln(cast(MyInt)result);
> }else{
>     writeln(cast(MyFloat)result);
> }
> ```
>
> Then I met the problem: I don't know to use which tool to get 
> the type of `result`. I've tried many ways but it didn't help.
> And strangely, I've met two cases like these code above 
> yesterday, but sometimes one writing method could work well, 
> but another couldn't. That made me surprised.

You might be thinking about this the wrong way.

1. The point of polymorphism is *not to care* about the type. You 
define the interface you need on the base type, and use that. 
Then the virtual functions naturally go to the right place.
2. casting is the way to confirm the type (to a degree). A cast 
from one object to another is a *dynamic* cast, and will return 
null if the type does not match.

>
> Can you solve the problem? What are the use of those keywords? 
> How to use them? Which I should use to fill in the `/*?????*/` 
> ? I'm waiting for you.

To answer your specific query, I have 2 solutions. First, you can 
check that the `TypeInfo` (the D RTTI structure) is the same as 
the one you expect. Otherwise, you can cast the type to each leaf 
and see if it is not null.

```d
// solution 1: (preferred)
if(auto r = cast(MyInt)result){
     writeln(r);
}else if(auto r = cast(MyFloat)result){
     writeln(r);
}

// solution 2:
if(typeid(result) is typeid(MyInt)){
     writeln(cast(MyInt)result);
}else{
     writeln(cast(MyFloat)result);
}
```

Solution 2 does not work if you have a deeper hierarchy. For 
example, if result is a derivative of `MyInt`, then solution 1 
would succeed, whereas solution 2 would fail.

As a further note, I know this is a toy example. But 
`Object.toString` is a virtual function. For this exercise, you 
really should just overload `toString` and `writeln(result)`.

-Steve


More information about the Digitalmars-d-learn mailing list