digitalmars.D.learn - Convert array to custom type when passing function argument
- Stefanos Baziotis (27/27) Apr 17 2019 I have a custom Buf struct (working as a simple vector)
- Adam D. Ruppe (14/18) Apr 17 2019 This is the "implicit construction" I sometimes talk about....
- Stefanos Baziotis (11/23) Apr 17 2019 Sorry if this has been asked again, I didn't find anything.
- Adam D. Ruppe (18/20) Apr 17 2019 Basically implicit construction was considered a mistake in C++
- Stefanos Baziotis (4/6) Apr 17 2019 What do you mean by out-out?
- Adam D. Ruppe (15/17) Apr 17 2019 In C++, if you define a struct/class, and constructors apply for
- Stefanos Baziotis (6/19) Apr 17 2019 Yes, thanks. :)
- =?UTF-8?Q?Ali_=c3=87ehreli?= (3/9) Apr 19 2019 So, Adam meant opt-out but wrote out-out. :)
I have a custom Buf struct (working as a simple vector) struct Buf(T) { size_t cap, len; T *data; nogc this(T[] arr) { reserve(arr.length); foreach(item; arr) { push(item); } } ... }; And I have a function like this: void test(Buf!(int) buf) { } I want to be able to make it work array-like to have compact function calls. Something like this: test([1,2,3]); Currently I have the constructor shown and with that I do: test(Buf!(int)([1,2,3]); which is compact but can it be done differently? Meaning, if a function takes a Buf!(T), can it also take a T[] and construct a Buf!(T) using some constructor? Thanks in advance!
Apr 17 2019
On Wednesday, 17 April 2019 at 12:20:49 UTC, Stefanos Baziotis wrote:I want to be able to make it work array-like to have compact function calls. Something like this: test([1,2,3]);This is the "implicit construction" I sometimes talk about.... and D doesn't support it, by design (alas). There's two options you can do: 1) offer an overload to your function that does the conversion: void test(Buf!int arr) { /* impl here */ } void test(int[] arr) { test(Buf!int(arr)); } // just forward to the other or 2) Offer a helper construction function you can call, like: Buf!int toBuf(int[] a) { return Buf!int(a); } and then you can call the function like test([1, 2, 3].toBuf); // calling your function at the end
Apr 17 2019
On Wednesday, 17 April 2019 at 12:48:52 UTC, Adam D. Ruppe wrote:This is the "implicit construction" I sometimes talk about.... and D doesn't support it, by design (alas).Sorry if this has been asked again, I didn't find anything. Do we know the reason why it is not supported?There's two options you can do: 1) offer an overload to your function that does the conversion: void test(Buf!int arr) { /* impl here */ } void test(int[] arr) { test(Buf!int(arr)); } // just forward to the other or 2) Offer a helper construction function you can call, like: Buf!int toBuf(int[] a) { return Buf!int(a); } and then you can call the function like test([1, 2, 3].toBuf); // calling your function at the endYes, I had done the 2), which means for 50 functions, I have another 50 functions. Because of the constructor these are one-liners but still, it's kind of ugly. I didn't know about the 3) thanks! I think it's not a very good solution for this kind of problems but cool otherwise. - Stefanos
Apr 17 2019
On Wednesday, 17 April 2019 at 15:23:06 UTC, Stefanos Baziotis wrote:Sorry if this has been asked again, I didn't find anything. Do we know the reason why it is not supported?Basically implicit construction was considered a mistake in C++ and D didn't want to repeat that mistake. Most code guides for C++ say to always (or almost always) mark your constructors with `explicit`, so D just makes that the only option. I argue C++'s mistake was *out-out* implicit construction, not the concept in general - I kinda wish D would allow it if you specifically asked for it in the type. Walter also says though implicit construction complicates function overloading rules and compiler error messages, and he doesn't think it is worth the cost to even try it with a new keyword (IIRC, I haven't had this chat with him for a while, so I might be misremembering). Again, his experience with it in C++ on several levels was negative and he wanted to simplify D so people are more likely to do the right thing. I actually agree with him 90% of the time... just I wish it was available there for the other cases still.
Apr 17 2019
On Wednesday, 17 April 2019 at 16:33:17 UTC, Adam D. Ruppe wrote:[...]Thanks for the info!I argue C++'s mistake was *out-out* implicit constructionWhat do you mean by out-out? - Stefanos
Apr 17 2019
On Wednesday, 17 April 2019 at 23:26:16 UTC, Stefanos Baziotis wrote:In C++, if you define a struct/class, and constructors apply for this. struct Test { Test(const char* foo) {} }; void cool(Test t) {} cool("string"); // works That works in C++, unless you mark that constructor with `explicit` struct Test { explicit Test(const char* foo) {} // this opts out of the cool thing above };I argue C++'s mistake was *out-out* implicit constructionWhat do you mean by out-out?
Apr 17 2019
On Wednesday, 17 April 2019 at 23:44:42 UTC, Adam D. Ruppe wrote:In C++, if you define a struct/class, and constructors apply for this. struct Test { Test(const char* foo) {} }; void cool(Test t) {} cool("string"); // works That works in C++, unless you mark that constructor with `explicit` struct Test { explicit Test(const char* foo) {} // this opts out of the cool thing above };Yes, thanks. :) Actually, I asked initially because in C++ you can do the thing I described. I thought that you meant something I missed with out-out. - Stefanos
Apr 17 2019
On 04/17/2019 05:21 PM, Stefanos Baziotis wrote:On Wednesday, 17 April 2019 at 23:44:42 UTC, Adam D. Ruppe wrote:explicit Test(const char* foo) {} // this opts out of the cool thing aboveActually, I asked initially because in C++ you can do the thing I described. I thought that you meant something I missed with out-out.So, Adam meant opt-out but wrote out-out. :) Ali
Apr 19 2019