www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 9066] New: Implement constructor forwarding template

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066

           Summary: Implement constructor forwarding template
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: andrej.mitrovich gmail.com



11:02:26 PST ---
This would alleviate the need to write boilerplate code by hand, e.g.:

class MyException : Exception
{
    mixin ForwardCtors;
}

An experimental implementation is provided in the attachment.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 23 2012
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066




11:02:46 PST ---
Created an attachment (id=1165)
code

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 23 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066




09:57:25 PST ---
*** Issue 8965 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 31 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066




12:00:13 PST ---
There's a few problems:

Default values aren't handled, and they could be initialized with a
non-accessible private value. The parameter types could also be private types
which might not be accessible.

It would definitely be simpler to implement inheriting constructors, C++11 has
them, described here:
http://stackoverflow.com/questions/9979194/what-is-constructor-inheritance

Perhaps we could implement something similar via:

class C : B
{
    alias super.this this;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 04 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066


Martin Nowak <code dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |code dawg.eu
            Summary|Implement constructor       |Implicit constructor
                   |forwarding template         |inheritance



I think what we want is implicit constructor inheritance even for non-default
constructors. The same rules should apply.

 Default values aren't handled, and they could be initialized with a
non-accessible private value.
Depends on the scope of default values, I'm not sure about this right now. If they live in the callee scope it'll work fine. If they live in the caller scope your constructor isn't callable from outside of the module and your constructor should be private.
 The parameter types could also be private types which might not be accessible.
Same here your constructor should be private. Old forum post on the topic of constructor inheritance. http://forum.dlang.org/thread/fqk4jb$n76$1 digitalmars.com -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 03 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066




04:09:58 PDT ---
Copying my comment from github:

C++11 has this feature: 
http://stackoverflow.com/questions/9979194/what-is-constructor-inheritance

I think the only real issue is what syntax to use in D. C++ uses:

-----
using Base::Base;
-----

At first glance in D it would be:

-----
alias Base.this this;  // or Super.this
-----

But this conflicts with the subtyping syntax.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 04 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066






Inheriting the default constructor is implicit so why would you need an
explicit syntax for non-default constructors?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 04 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066




11:37:43 PDT ---


 
 Inheriting the default constructor is implicit so why would you need an
 explicit syntax for non-default constructors?
The last time this was discussed (IIRC), people were against this. Maybe my memory is bad. We could have another go at a newsgroup discussion. I haven't yet looked at the C++11 spec, but I wonder why they too haven't made constructor inheritance implicit. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 04 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066




12:01:23 PDT ---


 
 Inheriting the default constructor is implicit so why would you need an
 explicit syntax for non-default constructors?
I guess the real issue is that you could easily end up instantiating an object which hasn't been properly initialized (properly meaning how the class designer defines it). For example: ----- class A { this(float x) { this.x = x; } float x; } class B : A { this(float x, float y) { super(x); this.y = y; } float y; } void main() { auto b = new B(1.0); // B's ctor not called } ----- Nevermind that we have .init, a class designer probably wants to have explicit control of which constructors can be called by the user. If all base class ctors are inherited.. well you saw the example. Another interesting example: ----- class A { this(float x) { this.x = x; } float x; } class B : A { this(float x, float y) { super(x); this.y = y; } const(float) y; } void main() { // this should not compile since y must be initialized // in the class B ctor, which wasn't called. auto b = new B(1.0); } ----- So the user could easily get a half-constructed object, or bad diagnostics about some const field not being initialized. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 04 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066






Your example wouldn't compile.
You can't default construct a class that defines a non-default constructor even
though we do have implicit constructor inheritance.
The rule here is very simple, if you define a constructor none is inherited.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 05 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066




09:59:19 PDT ---


 
 Your example wouldn't compile.
 You can't default construct a class that defines a non-default constructor even
 though we do have implicit constructor inheritance.
I'm not default-constructing a class in that example.
 The rule here is very simple, if you define a constructor none is inherited.
I see what you mean, that could work. Although I still want the ability to explicitly re-introduce base-class constructors via some syntax. So in essence we'll have: ----- class A { this(int); this(double); } class B : A { } // implicitly inherits ctors (very useful for Exception) ----- ----- class A { this(int); this(double); } class B : A { this(string); } // does *not* inherit ctors ----- I also want: ----- class A { this(int); this(double); } // inherit the this(int) ctor class B : A { this(string); alias super.this(int) this; } ----- However these two features can be implemented separately, so maybe we should split this up into two enhancement requests. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 05 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066





 class A { this(int); this(double); }
 
 // inherit the this(int) ctor
 class B : A { this(string); alias super.this(int) this; }
 -----
This is more specific because you have to specify which constructor to inherit by stating the parameter types. So you will save less typing over this(int a) { super(a); }. It's still useful because you can reuse the default arguments and the compiler will check for you that the parameter types match the base class. No good idea for the syntax though. Maybe we can special case the alias syntax as you used it in the example.
 so maybe we should split this up into two enhancement requests
Makes sense. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 05 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066




12:10:51 PDT ---

 This is more specific because you have to specify which constructor to inherit
 by stating the parameter types. So you will save less typing over this(int a) {
 super(a); }.
I'm thinking it would save the binary size though (save on duplicated functions that do nothing but forward arguments). Especially if you use a mixin template to autogenerate these (for whatever reason). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 05 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066





 I see what you mean, that could work. Although I still want the ability to
 explicitly re-introduce base-class constructors via some syntax. So in essence
 we'll have:
I had an idea how to achieve more flexibility with only a single special case for alias this. - We add implicit constructor inheritance. - When you define a constructor implicit inheritance is disabled. - We special case alias super.this this for explicit inheritance, it is invalid currently and has no useful semantic meaning. It's semantic meaning is overload the super class constructors with the local constructors. - You can use disable this(int) in the derived class to selectively disable some of the super class constructors. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 11 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9066


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |k.hara.pg gmail.com



11:21:54 PDT ---

 I had an idea how to achieve more flexibility with only a single
 special case for alias this.
Sounds good to me. Kenji what are your thoughts? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 11 2013