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

Reply via email to