casting to structure

Moritz Maxeiner via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jun 24 14:41:22 PDT 2017


On Saturday, 24 June 2017 at 20:43:48 UTC, Igor Shirkalin wrote:
> I'm in trouble with opCast function.
> Is it possible to cast some (integral) type to user defined 
> structure?

Hi, unfortunately not:
- Operator overloading is supported via member functions only [1].
- Corollary: You cannot overload operators for builtin types 
(i.e. where the cast gets rewritten to `e.opOverloaded` where `e` 
is a builtin type)
- opCast needs to be defined for the type that you are casting 
from [2], not the one you are casting to
=> You cannot overload opCast for casting from builtin types

> [...]
>
> How can we define opCast operator to make the following 
> expression working properly?
>
> auto a = cast(A) 12;

You cannot. As any such cast operation would have to create a new 
A object, anyway (and would as such be a wrapper around a 
(possibly default) constructor), I suggest using elaborate 
constructors:

---
struct A
{
     void* data;

     this(int data) { this.data = cast(void*) data; }
}

...

auto a = A(12);
---

>
> The task arised from core.sys.windows module. This module 
> defines a lot of windows specific types based on HANDLE: these 
> are HWND, HDC, HBITMAP, etc. The problem is that all these 
> types are identical, and it is too bad.

Why is this a problem? That *is* how the Windows C API works 
AFAIK.
Typesafety would require a higher abstraction level than the 
Windows C API functions provide, anyway.

> When I redefine these types like:
>        alias Typedef!(void*) HDC;
>
> I have another problem:
>
>   HWND_MESSAGE = cast(HWND) -3;  // Error: cannot cast 
> expression -3 of type int to Typedef!(void*, null, null)

You have explicitly asked for those two types to be different 
from each other [3]; that means they are also *not* implicitly 
convertible to each other and thus you also cannot cast from one 
to the other without defining an opCast (which you can't in this 
case, since the source type is a builtin type).

> So, is there any solution to this?

Define a struct for HWND as shown above for A and use 
constructors. Add an `alias this` to the wrapped pointer value.
Word of warning, though: What you're doing is highly unsafe.

[1] https://dlang.org/spec/operatoroverloading.html
[2] https://dlang.org/spec/operatoroverloading.html#cast
[3] https://dlang.org/phobos/std_typecons.html#.Typedef


More information about the Digitalmars-d-learn mailing list