www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Convert array to custom type when passing function argument

reply Stefanos Baziotis <sdi1600105 di.uoa.gr> writes:
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
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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
parent reply Stefanos Baziotis <sdi1600105 di.uoa.gr> writes:
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 end
Yes, 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
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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
parent reply Stefanos Baziotis <sdi1600105 di.uoa.gr> writes:
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 construction
What do you mean by out-out? - Stefanos
Apr 17 2019
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 17 April 2019 at 23:26:16 UTC, Stefanos Baziotis 
wrote:
 I argue C++'s mistake was *out-out* implicit construction
What do you mean by out-out?
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 };
Apr 17 2019
parent reply Stefanos Baziotis <sdi1600105 di.uoa.gr> writes:
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
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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 above
 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.
So, Adam meant opt-out but wrote out-out. :) Ali
Apr 19 2019