digitalmars.D - Explicit default constructor for structs
- Benjamin Thaut (55/55) Apr 09 2014 Just to be clear, I don't want a default constructor for structs that
- John Colvin (2/61) Apr 09 2014 This would be very nice. Yes please.
- monarch_dodra (4/7) Apr 09 2014 I haven't read though the entire proposal yet (sorry!), but I'm
- Brian Schott (14/14) Apr 09 2014 What would this do?
- Jacob Carlborg (4/18) Apr 09 2014 Result in an ambiguity error?
- Brian Schott (18/19) Apr 09 2014 Really? What does this program print using a current version of
- Jacob Carlborg (7/23) Apr 09 2014 Yeah, because currently DMD doesn't have the proposed feature. If it's
- Andrej Mitrovic (3/19) Apr 10 2014 This is a current bug that is going to be fixed:
- Remo (9/31) Apr 10 2014 Please do not forget about C++ porting problems that are related
- Jacob Carlborg (6/13) Apr 10 2014 How said anything about that? It has been said that one should be able
- monarch_dodra (13/28) Apr 10 2014 Well, it's true that the idea is that you can copy paste C code
- Daniel Murphy (3/5) Apr 11 2014 These expectations will lead to disappointment.
- Jonathan M Davis (17/24) Apr 11 2014 One of the goals of D was to make it so that when _C_ code was compiled ...
- Remo (10/16) Apr 11 2014 Why everyone here seems to confuse portion with copy and paste?
- Jonathan M Davis (9/28) Apr 11 2014 How easy it is to port C++ to D depends on what the code does. Some styl...
- Dicebot (3/6) Apr 11 2014 It does not work that way and has never worked. Think about class
- monarch_dodra (11/18) Apr 11 2014 Yeah. It'd say those wouldn't compile anyway, but I guess
- Jacob Carlborg (4/14) Apr 11 2014 Unless "doit" is non-virtual in both versions.
- monarch_dodra (5/19) Apr 11 2014 Why? The D version would just go from "object.Error Access
- Daniel Murphy (4/8) Apr 11 2014 Sadly I've encountered C++ code that deliberately calls member functions...
- Jonathan M Davis (15/26) Apr 11 2014 I've never seen code that it did it on purpose, but I've certainly seen ...
- Jacob Carlborg (6/10) Apr 11 2014 No, in release mode it's possible to call non-virtual methods on null
- monarch_dodra (4/14) Apr 11 2014 Right, the call will succeed, but if the function accesses any
- Jacob Carlborg (4/6) Apr 12 2014 Yeah, right.
- Benjamin Thaut (3/17) Apr 09 2014 Thats easy to answer. What would it do if you replace the "struct" with
- Brian Schott (2/4) Apr 09 2014 This thread is giving me some fun ideas for static analysis rules.
- Benjamin Thaut (4/8) Apr 09 2014 Just saying, if you do the same with a class, the default constructor is...
- Brian Schott (17/23) Apr 09 2014 As of a minute ago D-Scanner will warn about the following code:
- Jacob Carlborg (4/25) Apr 09 2014 What's the advantage over using a static opCall, that it works with "new...
- Benjamin Thaut (2/3) Apr 09 2014 That you can use it together with @disable this();
- Timon Gehr (11/22) Apr 09 2014 Why not just:
- Benjamin Thaut (7/18) Apr 09 2014 Because then the user might think, that the default constructor gets
- Timon Gehr (4/25) Apr 09 2014 This would be pointed out by the compiler. (i.e. it is an error instead
- Benjamin Thaut (5/33) Apr 09 2014 I don't know any use case. But AFAIK the reason there is no default
- Walter Bright (7/8) Apr 09 2014 Or you could use a factory function:
- Benjamin Thaut (3/11) Apr 09 2014 But I don't want the construction to be syntacically any different. I
- monarch_dodra (66/74) Apr 10 2014 Yeah. For sure.
- Atila Neves (2/68) Apr 10 2014
- deadalnix (2/8) Apr 27 2014 And they are all broken in their own ways.
- ketmar (8/11) Apr 26 2014 sorry for not reading the whole post and necroposting, but
- Temtaime (3/3) Apr 27 2014 People, why you hates ctors for structs ?
Just to be clear, I don't want a default constructor for structs that gets called implictly by the compiler, like in C++. Instead I would really love to have a explicit default constructor. E.g. it could look like this (alternative a new keyword "explicit" could be introduced, but introduction of new keywords is usually avoided if possible, AFAIK): struct Foo { this(void) { // do stuff here } } This default constructor would _never_ be called automatically by the compiler. (e.g. when a class is constructed that has struct members.) It would only be called in cases where the user explictly calls it. The following lines would call the explicit default constructor auto foo1 = Foo(); auto foo2 = new Foo(); foo1 = Foo(); // calls explicit constructor first, then calls assignment operator Whereas the follwing would _not_ call the explicit default constructor. class Bar { Foo m_foo; } auto bar = new Bar(); Foo foo; // does not call the explict default constructor, because there is no explicit call here I think this would fix all cases where you currently wish for a struct default constructor in D. Coupeled with " disable this();" you could force users to always call one of the struct constructors. Currently I work around the issue of not having any default constructors by doing this: struct DefaultCtor {}; //call default ctor type enum defaultCtor = DefaultCtor(); struct Foo() { disable this(); this(DefaultCtor) { // default constructor } this(int) { // other constructor } } auto foo = Foo(defaultCtor); While this works, I'm getting anoyed by it every day. For example when refactoring types from Classes to Structs and vise versa. As well as when placing Classes on the stack using a helper struct. Or when having RAII structs that don't take any paramters in their constructor. What do you think? C&C welcome. Kind Regards Benjamin Thaut
Apr 09 2014
On Wednesday, 9 April 2014 at 14:59:35 UTC, Benjamin Thaut wrote:Just to be clear, I don't want a default constructor for structs that gets called implictly by the compiler, like in C++. Instead I would really love to have a explicit default constructor. E.g. it could look like this (alternative a new keyword "explicit" could be introduced, but introduction of new keywords is usually avoided if possible, AFAIK): struct Foo { this(void) { // do stuff here } } This default constructor would _never_ be called automatically by the compiler. (e.g. when a class is constructed that has struct members.) It would only be called in cases where the user explictly calls it. The following lines would call the explicit default constructor auto foo1 = Foo(); auto foo2 = new Foo(); foo1 = Foo(); // calls explicit constructor first, then calls assignment operator Whereas the follwing would _not_ call the explicit default constructor. class Bar { Foo m_foo; } auto bar = new Bar(); Foo foo; // does not call the explict default constructor, because there is no explicit call here I think this would fix all cases where you currently wish for a struct default constructor in D. Coupeled with " disable this();" you could force users to always call one of the struct constructors. Currently I work around the issue of not having any default constructors by doing this: struct DefaultCtor {}; //call default ctor type enum defaultCtor = DefaultCtor(); struct Foo() { disable this(); this(DefaultCtor) { // default constructor } this(int) { // other constructor } } auto foo = Foo(defaultCtor); While this works, I'm getting anoyed by it every day. For example when refactoring types from Classes to Structs and vise versa. As well as when placing Classes on the stack using a helper struct. Or when having RAII structs that don't take any paramters in their constructor. What do you think? C&C welcome. Kind Regards Benjamin ThautThis would be very nice. Yes please.
Apr 09 2014
On Wednesday, 9 April 2014 at 14:59:35 UTC, Benjamin Thaut wrote:What do you think? C&C welcome. Kind Regards Benjamin ThautI haven't read though the entire proposal yet (sorry!), but I'm in definite agreement that *something* needs to be done to allow explicit but argument-less construction of structs.
Apr 09 2014
What would this do? struct SomeStruct { this(int i = 10) { this.i = i; } this(void) { this.i = 20; } int i; } auto s = SomeStruct();
Apr 09 2014
On 2014-04-09 18:59, Brian Schott wrote:What would this do? struct SomeStruct { this(int i = 10) { this.i = i; } this(void) { this.i = 20; } int i; } auto s = SomeStruct();Result in an ambiguity error? -- /Jacob Carlborg
Apr 09 2014
On Wednesday, 9 April 2014 at 17:07:13 UTC, Jacob Carlborg wrote:Result in an ambiguity error?Really? What does this program print using a current version of DMD? import std.stdio; struct SomeStruct { this(int i = 10) { this.i = i; } int i; } void main(string[] args) { auto s = SomeStruct(); writeln("s.i = ", s.i); } I don't think it would be ambiguous at all :-)
Apr 09 2014
On 2014-04-09 19:10, Brian Schott wrote:Really? What does this program print using a current version of DMD? import std.stdio; struct SomeStruct { this(int i = 10) { this.i = i; } int i; } void main(string[] args) { auto s = SomeStruct(); writeln("s.i = ", s.i); } I don't think it would be ambiguous at all :-)Yeah, because currently DMD doesn't have the proposed feature. If it's added I can imagine it's similar to writing this: void foo (); void foo (int i = 0); -- /Jacob Carlborg
Apr 09 2014
On 4/9/14, Brian Schott <briancschott gmail.com> wrote:Really? What does this program print using a current version of DMD? import std.stdio; struct SomeStruct { this(int i = 10) { this.i = i; } int i; } void main(string[] args) { auto s = SomeStruct(); writeln("s.i = ", s.i); }This is a current bug that is going to be fixed: https://github.com/D-Programming-Language/dmd/pull/1397
Apr 10 2014
On Thursday, 10 April 2014 at 11:39:16 UTC, Andrej Mitrovic wrote:On 4/9/14, Brian Schott <briancschott gmail.com> wrote:Please do not forget about C++ porting problems that are related to this. The code from C++ should compile and work as expected or does not compile at all and give meaningful error message. Right now it compiles but does not work at all. This struct constructor problem is one of the ground why I have stopped porting code to D. I hope there will be proper solution soon.Really? What does this program print using a current version of DMD? import std.stdio; struct SomeStruct { this(int i = 10) { this.i = i; } int i; } void main(string[] args) { auto s = SomeStruct(); writeln("s.i = ", s.i); }This is a current bug that is going to be fixed: https://github.com/D-Programming-Language/dmd/pull/1397
Apr 10 2014
On 2014-04-10 17:21, Remo wrote:Please do not forget about C++ porting problems that are related to this. The code from C++ should compile and work as expected or does not compile at all and give meaningful error message. Right now it compiles but does not work at all. This struct constructor problem is one of the ground why I have stopped porting code to D. I hope there will be proper solution soon.How said anything about that? It has been said that one should be able to paste C code in a D file and have it compile with the same resulting semantics as in C or not compile at all. But never for C++. -- /Jacob Carlborg
Apr 10 2014
On Thursday, 10 April 2014 at 19:28:16 UTC, Jacob Carlborg wrote:On 2014-04-10 17:21, Remo wrote:Well, it's true that the idea is that you can copy paste C code into D and it "just works", keeping the same semantics (provided minor/trivial tweaks). And nobody ever sold you could do the same thing with C++. *BUT*, if you happen to copy paste C++ code, and it *does* compile, then it is pretty much expected to keep the same resulting semantics, yes. The "this(Arg arg = someDefault)" is a flagrant example of something that should be rejected. Not only because it's stupid to write in plain D, but also because it creates gratuitous deviation from the behavior you'd get in C++. And that's actually very bad (IMO).Please do not forget about C++ porting problems that are related to this. The code from C++ should compile and work as expected or does not compile at all and give meaningful error message. Right now it compiles but does not work at all. This struct constructor problem is one of the ground why I have stopped porting code to D. I hope there will be proper solution soon.How said anything about that? It has been said that one should be able to paste C code in a D file and have it compile with the same resulting semantics as in C or not compile at all. But never for C++.
Apr 10 2014
"monarch_dodra" wrote in message news:rftskgfoeuvyeuvrusei forum.dlang.org...*BUT*, if you happen to copy paste C++ code, and it *does* compile, then it is pretty much expected to keep the same resulting semantics, yes.These expectations will lead to disappointment.
Apr 11 2014
On Friday, April 11, 2014 22:38:28 Daniel Murphy wrote:"monarch_dodra" wrote in message news:rftskgfoeuvyeuvrusei forum.dlang.org...One of the goals of D was to make it so that when _C_ code was compiled as D code, it either wouldn't compile or would have identical semantics, and I believe that that is still true save for a very short list of exceptions (the only ones that come to mind are that the calling conventions wouldn't be the same and that static arrays are value types in D whereas they're reference types in C). However, that's not at all true for C++. You're probably more likely to be able to port Java code directly and have it have the same semantics than C++ code. A shining example of that is the semantics for variables of class types. In C++, if they're not declared as pointers, then they're value types, whereas they're always reference types in D. Part of the whole point of D is to have better semantics than C++, so it's certainly not going to try and keep the same semantics as C++. For the most part, we haven't gratuitously changed the semantics, but there are a lot of places where we gained something by changing them, so we did. - Jonathan M Davis*BUT*, if you happen to copy paste C++ code, and it *does* compile, then it is pretty much expected to keep the same resulting semantics, yes.These expectations will lead to disappointment.
Apr 11 2014
On Friday, 11 April 2014 at 12:38:14 UTC, Daniel Murphy wrote:"monarch_dodra" wrote in message news:rftskgfoeuvyeuvrusei forum.dlang.org...Why everyone here seems to confuse portion with copy and paste? Of course C++ code that is just copy and pasted will not work or not work as expected. But I think (hope) that one of the advantage of D is that it allow to easily PORT C/C++ code. If this is not the case and was really not intended then it is probably better to use C++14 instate. Other advantage of D could be easy interconnection of C/C++ libraries and D...*BUT*, if you happen to copy paste C++ code, and it *does* compile, then it is pretty much expected to keep the same resulting semantics, yes.These expectations will lead to disappointment.
Apr 11 2014
On Friday, April 11, 2014 17:00:50 Remo wrote:On Friday, 11 April 2014 at 12:38:14 UTC, Daniel Murphy wrote:How easy it is to port C++ to D depends on what the code does. Some styles of code and types of operations will port over very easily, whereas others would require a fair bit of refactoring. For the most part, the changes that you'd be forced to make would be for the better, but if a lot of your code is doing stuff that doesn't port easily, then it could be painful to port. Personally, I'd probably rewrite the code in D and just use the C++ as a reference rather than trying to really port it. - Jonathan M Davis"monarch_dodra" wrote in message news:rftskgfoeuvyeuvrusei forum.dlang.org...Why everyone here seems to confuse portion with copy and paste? Of course C++ code that is just copy and pasted will not work or not work as expected. But I think (hope) that one of the advantage of D is that it allow to easily PORT C/C++ code. If this is not the case and was really not intended then it is probably better to use C++14 instate. Other advantage of D could be easy interconnection of C/C++ libraries and D...*BUT*, if you happen to copy paste C++ code, and it *does* compile, then it is pretty much expected to keep the same resulting semantics, yes.These expectations will lead to disappointment.
Apr 11 2014
On Thursday, 10 April 2014 at 21:23:43 UTC, monarch_dodra wrote:>*BUT*, if you happen to copy paste C++ code, and it *does* compile, then it is pretty much expected to keep the same resulting semantics, yes.It does not work that way and has never worked. Think about class semantics for example.
Apr 11 2014
On Friday, 11 April 2014 at 12:58:09 UTC, Dicebot wrote:On Thursday, 10 April 2014 at 21:23:43 UTC, monarch_dodra wrote:>Yeah. It'd say those wouldn't compile anyway, but I guess something as trivial as: //---- class A {...} A a; a.doit; //---- Would compile for both languages, but give different results. Fine.*BUT*, if you happen to copy paste C++ code, and it *does* compile, then it is pretty much expected to keep the same resulting semantics, yes.It does not work that way and has never worked. Think about class semantics for example.
Apr 11 2014
On 2014-04-11 15:53, monarch_dodra wrote:Yeah. It'd say those wouldn't compile anyway, but I guess something as trivial as: //---- class A {...} A a; a.doit; //---- Would compile for both languages, but give different results. Fine.Unless "doit" is non-virtual in both versions. -- /Jacob Carlborg
Apr 11 2014
On Friday, 11 April 2014 at 15:54:36 UTC, Jacob Carlborg wrote:On 2014-04-11 15:53, monarch_dodra wrote:Why? The D version would just go from "object.Error Access Violation" to "AssertError null this". And in release, you'd still (highly probably) still get the Access Violation.Yeah. It'd say those wouldn't compile anyway, but I guess something as trivial as: //---- class A {...} A a; a.doit; //---- Would compile for both languages, but give different results. Fine.Unless "doit" is non-virtual in both versions.
Apr 11 2014
"monarch_dodra" wrote in message news:ktbdlcaqahsqmwkiddvc forum.dlang.org...Why? The D version would just go from "object.Error Access Violation" to "AssertError null this". And in release, you'd still (highly probably) still get the Access Violation.Sadly I've encountered C++ code that deliberately calls member functions on null class pointers.
Apr 11 2014
On Saturday, April 12, 2014 02:26:54 Daniel Murphy wrote:"monarch_dodra" wrote in message news:ktbdlcaqahsqmwkiddvc forum.dlang.org...I've never seen code that it did it on purpose, but I've certainly seen code that did it on accident. And what's really fun is when it's non-virtual, because that won't segfault on the call - only when it does something inside the function which causes the this pointer to be dereferenced (e.g accessing a member variable or virtual member function). _That_ can really confuse people when it happens. At one point at work, we had a class that was never instantiated but worked great (it really didn't need to be a class at all, just free functions, as it didn't actually have any member variables). Fortunately, I'd seen the problem before and could explain to the others once I remembered, but no one else on the team had ever seen anything like it and all found it quite surprising. _I_ was certainly shocked by it when I originally ran into it - though it all makes sense when you look at what the compiler needs to do when calling a function. - Jonathan M DavisWhy? The D version would just go from "object.Error Access Violation" to "AssertError null this". And in release, you'd still (highly probably) still get the Access Violation.Sadly I've encountered C++ code that deliberately calls member functions on null class pointers.
Apr 11 2014
On 2014-04-11 18:05, monarch_dodra wrote:Why? The D version would just go from "object.Error Access Violation" to "AssertError null this".Hmm, I was pretty sure it wouldn't assert.And in release, you'd still (highly probably) still get the Access Violation.No, in release mode it's possible to call non-virtual methods on null references. -- /Jacob Carlborg
Apr 11 2014
On Friday, 11 April 2014 at 20:36:12 UTC, Jacob Carlborg wrote:On 2014-04-11 18:05, monarch_dodra wrote:Right, the call will succeed, but if the function accesses any class members, it will access violation *there*. Hence the "highly likely".Why? The D version would just go from "object.Error Access Violation" to "AssertError null this".Hmm, I was pretty sure it wouldn't assert.And in release, you'd still (highly probably) still get the Access Violation.No, in release mode it's possible to call non-virtual methods on null references.
Apr 11 2014
On 2014-04-11 22:48, monarch_dodra wrote:Right, the call will succeed, but if the function accesses any class members, it will access violation *there*. Hence the "highly likely".Yeah, right. -- /Jacob Carlborg
Apr 12 2014
Am 09.04.2014 18:59, schrieb Brian Schott:What would this do? struct SomeStruct { this(int i = 10) { this.i = i; } this(void) { this.i = 20; } int i; } auto s = SomeStruct();Thats easy to answer. What would it do if you replace the "struct" with "class" and the "void" with nothing?
Apr 09 2014
On Wednesday, 9 April 2014 at 18:47:41 UTC, Benjamin Thaut wrote:Thats easy to answer. What would it do if you replace the "struct" with "class" and the "void" with nothing?This thread is giving me some fun ideas for static analysis rules.
Apr 09 2014
Am 09.04.2014 20:53, schrieb Brian Schott:On Wednesday, 9 April 2014 at 18:47:41 UTC, Benjamin Thaut wrote:Just saying, if you do the same with a class, the default constructor is picked and not the one with the default argument. So it should do the same for structs.Thats easy to answer. What would it do if you replace the "struct" with "class" and the "void" with nothing?This thread is giving me some fun ideas for static analysis rules.
Apr 09 2014
On Wednesday, 9 April 2014 at 18:53:20 UTC, Brian Schott wrote:On Wednesday, 9 April 2014 at 18:47:41 UTC, Benjamin Thaut wrote:As of a minute ago D-Scanner will warn about the following code: class TestClass { this() { i = 10; } this(int i = 20) { this.i = i; } int i; } struct Bogus { this(int x = 0) {} } test.d(1:7)[warn]: This class has a zero-argument constructor as well as a constructor with one default argument. This can be confusing test.d(10:2)[warn]: This struct constructor can never be called with its default argument.Thats easy to answer. What would it do if you replace the "struct" with "class" and the "void" with nothing?This thread is giving me some fun ideas for static analysis rules.
Apr 09 2014
On 2014-04-09 16:59, Benjamin Thaut wrote:Just to be clear, I don't want a default constructor for structs that gets called implictly by the compiler, like in C++. Instead I would really love to have a explicit default constructor. E.g. it could look like this (alternative a new keyword "explicit" could be introduced, but introduction of new keywords is usually avoided if possible, AFAIK): struct Foo { this(void) { // do stuff here } } This default constructor would _never_ be called automatically by the compiler. (e.g. when a class is constructed that has struct members.) It would only be called in cases where the user explictly calls it. The following lines would call the explicit default constructor auto foo1 = Foo(); auto foo2 = new Foo(); foo1 = Foo(); // calls explicit constructor first, then calls assignment operatorWhat's the advantage over using a static opCall, that it works with "new"? -- /Jacob Carlborg
Apr 09 2014
Am 09.04.2014 19:05, schrieb Jacob Carlborg:What's the advantage over using a static opCall, that it works with "new"?That you can use it together with disable this();
Apr 09 2014
On 04/09/2014 04:59 PM, Benjamin Thaut wrote:Instead I would really love to have a explicit default constructor. E.g. it could look like this (alternative a new keyword "explicit" could be introduced, but introduction of new keywords is usually avoided if possible, AFAIK): struct Foo { this(void) { // do stuff here } }Why not just: struct Foo{ this(){ // do stuff here } } void main(){ Foo foo1; // error, no init value auto foo2=Foo(); // ok }
Apr 09 2014
Am 09.04.2014 20:33, schrieb Timon Gehr:On 04/09/2014 04:59 PM, Benjamin Thaut wrote:Why not just: struct Foo{ this(){ // do stuff here } } void main(){ Foo foo1; // error, no init value auto foo2=Foo(); // ok }Because then the user might think, that the default constructor gets called implicitly by the compiler. Just like in C++. But as that is not the case the syntax should be different to indicate that a struct might still be instaniated just using T.init. Kind Regards Benjamin Thaut
Apr 09 2014
On 04/09/2014 08:53 PM, Benjamin Thaut wrote:Am 09.04.2014 20:33, schrieb Timon Gehr:This would be pointed out by the compiler. (i.e. it is an error instead of an implicit call.)On 04/09/2014 04:59 PM, Benjamin Thaut wrote:Why not just: struct Foo{ this(){ // do stuff here } } void main(){ Foo foo1; // error, no init value auto foo2=Foo(); // ok }Because then the user might think, that the default constructor gets called implicitly by the compiler.Just like in C++. But as that is not the case the syntax should be different to indicate that a struct might still be instaniated just using T.init. Kind Regards Benjamin ThautWhat would be an use case for a bypassable default constructor?
Apr 09 2014
Am 09.04.2014 21:02, schrieb Timon Gehr:On 04/09/2014 08:53 PM, Benjamin Thaut wrote:I don't know any use case. But AFAIK the reason there is no default constructor for structs in D has to do something with exception safetey. So whatever cases those are, they might need a bypassable default constructor.Am 09.04.2014 20:33, schrieb Timon Gehr:This would be pointed out by the compiler. (i.e. it is an error instead of an implicit call.)On 04/09/2014 04:59 PM, Benjamin Thaut wrote:Why not just: struct Foo{ this(){ // do stuff here } } void main(){ Foo foo1; // error, no init value auto foo2=Foo(); // ok }Because then the user might think, that the default constructor gets called implicitly by the compiler.Just like in C++. But as that is not the case the syntax should be different to indicate that a struct might still be instaniated just using T.init. Kind Regards Benjamin ThautWhat would be an use case for a bypassable default constructor?
Apr 09 2014
On 4/9/2014 7:59 AM, Benjamin Thaut wrote:What do you think? C&C welcome.Or you could use a factory function: struct Foo { static Foo factory() { ... } ... } auto foo = Foo.factory();
Apr 09 2014
Am 09.04.2014 20:42, schrieb Walter Bright:On 4/9/2014 7:59 AM, Benjamin Thaut wrote:But I don't want the construction to be syntacically any different. I know there are workarounds, but after all they are workarounds.What do you think? C&C welcome.Or you could use a factory function: struct Foo { static Foo factory() { ... } ... } auto foo = Foo.factory();
Apr 09 2014
On Wednesday, 9 April 2014 at 18:41:57 UTC, Walter Bright wrote:On 4/9/2014 7:59 AM, Benjamin Thaut wrote:Yeah. For sure. Or a named function: auto foo = foo(); Or a make template: auto foo = make!Foo(); Or a dummy argument: auto foo = Foo(Foo.dummy); Or ditto with a global dummy: auto foo = Foo(dummyArg); Or use a static opCall: auto foo = Foo(); Or use an initialize function: Foo foo; foo.initialize(); I mean: Why complain when there are at least 10 *different* solutions at our disposal? Who doesn't love re-inventing the same functionality over and over and over again? But more importantly, who doesn't just *love* reading the documentation that explains *which* approach the damn type chose for run-time initialization. Yummy! Also, any kind of "Factory" solution has a postblit overhead if you try to emplace it. Or would require a temporary with some complex "uninitializedMove". No postblit, but still overhead. -------- Being serious again, if the language isn't going to do something to address the issue, we *should* have a uniform library solution. I think the "make" template could be a good approach. It could be a universal construction scheme, with "opt-in" no-arg construction: static struct NoArg {} enum noArgToken; template make(T) { //And some switches to handle non-struct types too. T make(Args...)(auto ref Args args) { static if (Args.length) return T(args); else { static if (is(typeof(T(noArgToken)))); return T(noArgToken); else return T(); } } } struct S1 { int* p; disable this(); this(NoArg) //Opt-in no-arg constructor {p = new int;} } struct S2 { int i; } void main() { S1 s11; //FAils to compile (disabled this()); auto s12 = S1.init; //Explicit request for static default initialization; auto s13 = make!S1(); //run-time construction request. auto s2 = make!S2(); //run-time construction request. Does nothing particular. } This has the advantage (IMO) of being explicit and universal. Also, it's an actual construction scheme, so `emplace(noArgToken)` would call an actual constructor. Furthermore, it could also allow a universal construction scheme for items, regardless of struct/class/integral etc...What do you think? C&C welcome.Or you could use a factory function: struct Foo { static Foo factory() { ... } ... } auto foo = Foo.factory();
Apr 10 2014
+1 AtilaYeah. For sure. Or a named function: auto foo = foo(); Or a make template: auto foo = make!Foo(); Or a dummy argument: auto foo = Foo(Foo.dummy); Or ditto with a global dummy: auto foo = Foo(dummyArg); Or use a static opCall: auto foo = Foo(); Or use an initialize function: Foo foo; foo.initialize(); I mean: Why complain when there are at least 10 *different* solutions at our disposal? Who doesn't love re-inventing the same functionality over and over and over again? But more importantly, who doesn't just *love* reading the documentation that explains *which* approach the damn type chose for run-time initialization. Yummy! Also, any kind of "Factory" solution has a postblit overhead if you try to emplace it. Or would require a temporary with some complex "uninitializedMove". No postblit, but still overhead. -------- Being serious again, if the language isn't going to do something to address the issue, we *should* have a uniform library solution. I think the "make" template could be a good approach. It could be a universal construction scheme, with "opt-in" no-arg construction: static struct NoArg {} enum noArgToken; template make(T) { //And some switches to handle non-struct types too. T make(Args...)(auto ref Args args) { static if (Args.length) return T(args); else { static if (is(typeof(T(noArgToken)))); return T(noArgToken); else return T(); } } } struct S1 { int* p; disable this(); this(NoArg) //Opt-in no-arg constructor {p = new int;} } struct S2 { int i; } void main() { S1 s11; //FAils to compile (disabled this()); auto s12 = S1.init; //Explicit request for static default initialization; auto s13 = make!S1(); //run-time construction request. auto s2 = make!S2(); //run-time construction request. Does nothing particular. } This has the advantage (IMO) of being explicit and universal. Also, it's an actual construction scheme, so `emplace(noArgToken)` would call an actual constructor. Furthermore, it could also allow a universal construction scheme for items, regardless of struct/class/integral etc...
Apr 10 2014
On Thursday, 10 April 2014 at 11:13:45 UTC, monarch_dodra wrote:Or a named function: auto foo = foo(); Or a make template: auto foo = make!Foo(); Or a dummy argument: auto foo = Foo(Foo.dummy); Or ditto with a global dummy: auto foo = Foo(dummyArg); Or use a static opCall: auto foo = Foo(); Or use an initialize function: Foo foo; foo.initialize();And they are all broken in their own ways.
Apr 27 2014
On Wednesday, 9 April 2014 at 14:59:35 UTC, Benjamin Thaut wrote:E.g. it could look like this (alternative a new keyword "explicit" could be introduced, but introduction of new keywords is usually avoided if possible, AFAIK):sorry for not reading the whole post and necroposting, but please, please, please vote for new keywords! please, stop suggesting obscure features that cannot be logicaly deducted! ' explicit' attribute can work fine here, and 'this(void)' is impossible to understand without carefull *studying* the documentation. and it is really easy to miss when reading the code.
Apr 26 2014
People, why you hates ctors for structs ? "Default ctor" - simple a workaround. Just allow ctors with structs and it's all.
Apr 27 2014