Jump to page: 1 2
Thread overview
Improvement to struct inheritance possible?
Jan 18
Danilo
Jan 18
zjh
Jan 18
zjh
Jan 18
zjh
Jan 18
Danilo
Jan 18
Meta
Jan 19
Danilo
Jan 19
Danilo
Jan 19
Danilo
January 18

The following code does not work, and I think it may be a bug or could need an enhancement:

module app;
import std;

void main() {
    auto x = new Derived(10, 20);
}

struct Base {
    int a;
}

struct Derived
{
    Base base;
    int b;
    alias this = base;

    @disable this();

    // `a` is not available for use with constructor parameters.
    //
    this( typeof(a) _a, typeof(b) _b ) {
        //
        // inside the body of the constructor, `a` is available!
        //
        a = _a;
        b = _b;

        writeln( a, ", ", b );
    }
}

The use of typeof(a) as a constructor parameter gives:
Error: undefined identifier a

Instead I have to explicitely use:

this( typeof(this.a) _a, typeof(b) _b )
// or
this( typeof(base.a) _a, typeof(b) _b )

I think this may be a bug, because base was imported into the scope using alias this = base and should therefore be available as plain a.

With class inheritance everything works as expected:

module app;

import std;

class A {
    int x;
}

class B : A {
    int y;
}

class C : B {
    int z;

    this( typeof(x) _x, typeof(y) _y, typeof(z) _z) {
        writeln(
            _x, ", ",
            _y, ", ",
            _z
        );
    }
}

void main() {
    new C(10, 20, 30);
}

Could this please get improved a little bit, so "inherited" structure members using alias this are already available for constructor paramaters?

Thanks!

January 18

On Thursday, 18 January 2024 at 07:10:49 UTC, Danilo wrote:

>

Could this please get improved a little bit, so "inherited" structure members using alias this are already available for constructor paramaters?

Thanks!

Why can't struct be inherited ?C++ has good struct inheritance, and it's there.
The disadvantage of C++ inheritance is that every subclass with a template now needs to add its own name and ugly ::, which is becoming increasingly unsightly! This is very foolish,

January 18

On Thursday, 18 January 2024 at 07:28:22 UTC, zjh wrote:

>

Why can't struct be inherited ?C++ has good struct inheritance, and it's there.
The disadvantage of C++ inheritance is that every subclass with a template now needs to add its own name and ugly ::, which is becoming increasingly unsightly! This is very foolish,

I look forward to someone writing a compiler plugin that can compensate for these shortcomings. If the compiler allows various plugins, it would be very good.

Plugins are completely selectable by users, which is equivalent to placing all the switches of 'dmd' in a separate plugins directory .

January 18

On Thursday, 18 January 2024 at 07:32:56 UTC, zjh wrote:

>

Plugins are completely selectable by users, which is equivalent to placing all the switches of 'dmd' in a separate plugins directory .

Then if you compile someone else's code, of course you need a plugin that someone else uses. However, there should be a compilation command that can control the switch of the plugin.
Moreover, each library comes with its own 'compile command' when released.

January 18

On Thursday, 18 January 2024 at 07:37:10 UTC, zjh wrote:

>

Then if you compile someone else's code, of course you need a plugin that someone else uses. However, there should be a compilation command that can control the switch of the plugin.
Moreover, each library comes with its own 'compile command' when released.

Can you please start your own thread?

Your messages have absolutely nothing to do with my issue/request!

January 18

On Thursday, 18 January 2024 at 07:10:49 UTC, Danilo wrote:

>

The following code does not work, and I think it may be a bug or could need an enhancement:

module app;
import std;

void main() {
    auto x = new Derived(10, 20);
}

struct Base {
    int a;
}

struct Derived
{
    Base base;
    int b;
    alias this = base;

    @disable this();

    // `a` is not available for use with constructor parameters.
    //
    this( typeof(a) _a, typeof(b) _b ) {
        //
        // inside the body of the constructor, `a` is available!
        //
        a = _a;
        b = _b;

        writeln( a, ", ", b );
    }
}

The use of typeof(a) as a constructor parameter gives:
Error: undefined identifier a

Instead I have to explicitely use:

this( typeof(this.a) _a, typeof(b) _b )
// or
this( typeof(base.a) _a, typeof(b) _b )

Just FYI, it's kind of a special case that typeof(this) works in this context -- there is no "this" at declaration level, it only exists as a parameter to a function. D allows using typeof(this) to mean "the type of an instance" during declarations because it would be awful otherwise.

So I think you are playing around the edge of this "special case" and that's why it's not working.

I'm actually surprised typeof(this.a) works.

-Steve

January 18

On Thursday, 18 January 2024 at 07:10:49 UTC, Danilo wrote:

>

The following code does not work, and I think it may be a bug or could need an enhancement:

module app;
import std;

void main() {
    auto x = new Derived(10, 20);
}

struct Base {
    int a;
}

struct Derived
{
    Base base;
    int b;
    alias this = base;

    @disable this();

    // `a` is not available for use with constructor parameters.
    //
    this( typeof(a) _a, typeof(b) _b ) {
        //
        // inside the body of the constructor, `a` is available!
        //
        a = _a;
        b = _b;

        writeln( a, ", ", b );
    }
}

The use of typeof(a) as a constructor parameter gives:
Error: undefined identifier a

Instead I have to explicitely use:

this( typeof(this.a) _a, typeof(b) _b )
// or
this( typeof(base.a) _a, typeof(b) _b )

I think this may be a bug, because base was imported into the scope using alias this = base and should therefore be available as plain a.

With class inheritance everything works as expected:

module app;

import std;

class A {
    int x;
}

class B : A {
    int y;
}

class C : B {
    int z;

    this( typeof(x) _x, typeof(y) _y, typeof(z) _z) {
        writeln(
            _x, ", ",
            _y, ", ",
            _z
        );
    }
}

void main() {
    new C(10, 20, 30);
}

Could this please get improved a little bit, so "inherited" structure members using alias this are already available for constructor paramaters?

Thanks!

This won't work because alias this is not inheritance ini the object oriented, class-based sense. All it does is when you try to access a symbol through a Derived struct (e.g. Derived d; writeln(d.a);) that the compiler sees does not exist in Derived, it will rewrite that to Derived d; writeln(d.base.a); (and also when you pass a Derived to a method taking a Base, it will automatically be rewritten to pass the Derived struct's Base member to the method instead).

You really cannot think of alias this as inheritance, because it is not at all the same as the object-oriented concept of inheritance. You'll only run into problems thinking of it that way.

January 18
On Thursday, January 18, 2024 12:10:49 AM MST Danilo via Digitalmars-d wrote:
> The following code does not work, and I think it may be a bug or could need an enhancement:
...

> Could this please get improved a little bit, so "inherited" structure members using `alias this` are already available for constructor paramaters?


The purpose of alias this is to add an implicit conversion to the target. Inside of a struct, it does do some extra work when a symbol isn't recognized and then implicitly converts the this parameter using the alias this to see if that allows the symbol to work, but at its core, alias this really has nothing to do with inheritance. It's just an implicit conversion (and if anything, personally, I think that doing the implicit conversion on the this reference when it's not even explicitly used is just begging for trouble, and I wish that that had not been implemented).

As for typeof, having it do implicit conversions seems like it would just be an avenue for bugs. And the situation with classes is completely different, because the members of a base class are actually members of the derived class, not simply brought in via implicit conversion.

In general, alias this is a giant footgun - especially in the face of any kind of type introspection - and IMHO, you really should reconsider what you're doing any time that you use it. Unfortunately, it can be necessary for certain classes of things, but extending it to do more is probably the exact opposite of what we should be doing with it if we change it.

-  Jonathan M Davis



January 19

Thanks for all the replies!

Of course the part "struct inheritance" was nonsense.
The problem has nothing to do with, it's just about
alias this = xyz inside classes and structs.

On Thursday, 18 January 2024 at 20:43:30 UTC, Meta wrote:

>

All it does is when you try to access a symbol through a Derived struct (e.g. Derived d; writeln(d.a);) that the compiler sees does not exist in Derived, it will rewrite that to Derived d; writeln(d.base.a);

Perfect! Only thing is missing, that this works everywhere
inside classes and structs - including method/constructor parameters.

If a isn't found, replace it with base.a.

January 19

On Thursday, 18 January 2024 at 21:06:22 UTC, Jonathan M Davis wrote:

>

As for typeof, having it do implicit conversions seems like it would just be an avenue for bugs.

It's not typeof() that does it, it's the compiler that does it
in the same way it usually does it. See answer to Meta, above.

alias this = xyz inside classes and structs:

  1. It's useful. And it's allowed to use it like in my first example, for "importing a struct into the main scope". I discovered the small issue when writing a constructor generator, and with this struct it didn't work.

  2. It's also about consistency:

    In my opinion the (virtual) alias created by alias this = xyz
    inside struct/class needs to work everywhere inside the same class/struct.

    That's why asked if it may be a bug. It's at least an issue if it works only partly.
    Seen from a programming language design viewpoint,
    I think it should get enhanced a tiny bit to be more consistent.

« First   ‹ Prev
1 2