March 31, 2021
On Tuesday, 30 March 2021 at 19:33:31 UTC, novice2 wrote:
> On Tuesday, 30 March 2021 at 19:12:29 UTC, Ali Çehreli wrote:
>> "Derived type" is used in the context of object oriented programming at least in D
>
> Sorry, i use wrong termin.
> I just want create new type Tnew, based on exist type Tbase.
> Tnew have same allowed values, same properties, same allowed operations as Tbase.
> Compiler should distinguish New from Tbase.
> Allowed implicit cast Tnew to Tbase.
> Prohibited implicit cast Tbase to Tnew.
> Allowed exlicit cast Tbase to Tnew.

That's precisely what the alias this feature is intended to do.

https://dlang.org/spec/class.html#alias-this

> Thanks, this is what i want.
> I just think that Typedef do it for me, hide this boilerplait code.

That's not the intended purpose of the Typedef template. Its documentation explicitly says it "allows the creation of a unique type which is based on an existing type". The keyword there is *unique*.
March 31, 2021
On Tuesday, 30 March 2021 at 21:53:34 UTC, Basile B. wrote:
> struct Typedef(TBase)
> {
>    TBase payload;
>    alias payload this;
> }
>
> alias Xobj = Typedef!(void*);

This is how std.typecons.Typedef made, IMHO.

The problem is this code generate struct with name "Typedef!(void*)",
then compiler show this name (not "Xobj") in messages:

https://run.dlang.io/is/eEI2yC

  void* bad;
  foo(bad);

Error: function foo(Typedef!(void*) obj) is not callable using argument types (void*)
       cannot pass argument bad of type void* to parameter Typedef!(void*) obj

March 31, 2021
On Wednesday, 31 March 2021 at 04:49:50 UTC, novice3 wrote:
> On Tuesday, 30 March 2021 at 21:53:34 UTC, Basile B. wrote:
>> struct Typedef(TBase)
>> {
>>    TBase payload;
>>    alias payload this;
>> }
>>
>> alias Xobj = Typedef!(void*);
>
> This is how std.typecons.Typedef made, IMHO.
>
> The problem is this code generate struct with name "Typedef!(void*)",
> then compiler show this name (not "Xobj") in messages:
>
> https://run.dlang.io/is/eEI2yC
>
>   void* bad;
>   foo(bad);
>
> Error: function foo(Typedef!(void*) obj) is not callable using argument types (void*)
>        cannot pass argument bad of type void* to parameter Typedef!(void*) obj

yeah template instances are identified using the parameters identifiers, then the alias is just a syntactic shortcut to that, not producing a new symbol with a unique mangle... but the message is correct assuming you want void* to be rejected.

That being said you can still use a string mixin if the messages have to be correct

---
string genTypeDef(TBase)(string name)
{
    return "struct " ~ name ~ "{" ~ TBase.stringof ~ " payload; alias payload this;}";
}

mixin(genTypeDef!(void*)("Xobj"));

void foo (Xobj obj) {}
---
March 31, 2021
On Wednesday, 31 March 2021 at 12:09:33 UTC, Basile B. wrote:
> yeah template instances are identified using the parameters identifiers, then the alias is just a syntactic shortcut to that, not producing a new symbol with a unique mangle...

so, no way to generate struct with parametrized name by template or mixin template?


> That being said you can still use a string mixin if the messages have to be correct
> ...

thank you!
April 01, 2021

On Tuesday, 30 March 2021 at 19:02:09 UTC, novice2 wrote:

>

[...]

Strange syntax.
Behavour exactly what i want, but this code not works for me :(

enum Xobj : void*;
Xobj var; //DMD Error: enum test7.Xobj forward reference of Xobj.init

You can add a custom init value if you want to allow one:

enum Xobj : void* { init = null }
April 01, 2021

On Thursday, 1 April 2021 at 12:07:17 UTC, WebFreak001 wrote:

>

You can add a custom init value if you want to allow one:

enum Xobj : void* { init = null }

Thank you!

April 01, 2021

thanks, i tried 2 variants:

struct Tnew {TBase payload; alias payload this;}
enum Tnew : Tbase {init = Tbase.init}

both works, but 1-st not allow "2 level" cast:

struct Xptr {void* payload; alias payload this;} //Xptr based on void*
struct Xobj {Xptr payload; alias payload this;}  //Xobj based on  Xptr
Xptr xptr = cast(Xptr) null;             //OK
Xobj xobj = cast(Xobj) null;             //ERROR
Xobj xobj = cast(Xobj) cast(Xptr) null;  //OK, needs both levels explitity
enum Xptr : void* {init = (void*).init} //Xptr based on void*
enum Xobj : Xptr {init = Xptr.init}     //Xobj based on  Xptr
Xptr xptr = cast(Xptr) null;            //OK
Xobj xobj = cast(Xobj) null;            //OK

so "enum" variant is better for me, thanks!

1 2
Next ›   Last »