Thread overview | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 26, 2013 Bypassing the postblit? | ||||
---|---|---|---|---|
| ||||
Dear D Experts I have a situation where I want to pass a D struct object as an argument to a function. Now in my case, I do not want to invoke the default D copy constructor for the struct. Is there a way of doing that? I have tried disabling the postblit and enabling another constructor via "alias this" (see the code below). But the compiler does not like that, and I get an error that tells me that the Bar is not copyable since it has been disabled: struct Bar { @disable this(this); alias _foo this; Foo _foo; public this(Foo foo) { this._foo = foo; } } class Foo {} void main() { Bar bar; Bar baz = bar; } Regards Ritu |
December 26, 2013 Re: Bypassing the postblit? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ritu | On Thursday, 26 December 2013 at 05:06:26 UTC, Ritu wrote:
> Dear D Experts
>
> I have a situation where I want to pass a D struct object as an argument to a function. Now in my case, I do not want to invoke the default D copy constructor for the struct. Is there a way of doing that? I have tried disabling the postblit and enabling another constructor via "alias this" (see the code below). But the compiler does not like that, and I get an error that tells me that the Bar is not copyable since it has been disabled:
>
> struct Bar {
> @disable this(this);
> alias _foo this;
> Foo _foo;
> public this(Foo foo) {
> this._foo = foo;
> }
> }
>
> class Foo {}
>
> void main() {
> Bar bar;
> Bar baz = bar;
> }
>
> Regards
> Ritu
D struct copying is done by a bit-level copy of the source. A postblit - the closest we have to a struct copy constructor - is only run if you specify one yourself, i.e. there is no default one to disable.
|
December 27, 2013 Re: Bypassing the postblit? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin |
> D struct copying is done by a bit-level copy of the source. A postblit - the closest we have to a struct copy constructor - is only run if you specify one yourself, i.e. there is no default one to disable.
Thanks John
Ok. Let me rephrase the question. I do not want to perform bit-wise copy of my struct, but I want to specify my own copy semantics. Is there a way?
Regards
Ritu
|
December 27, 2013 Re: Bypassing the postblit? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ritu | On 12/26/2013 05:43 PM, Ritu wrote: >> D struct copying is done by a bit-level copy of the source. A postblit >> - the closest we have to a struct copy constructor - is only run if >> you specify one yourself, i.e. there is no default one to disable. > > Thanks John > > Ok. Let me rephrase the question. I do not want to perform bit-wise copy > of my struct, but I want to specify my own copy semantics. Is there a way? No. In D, struct are freely copied or moved depending on whether the source is an lvalue or an rvalue. What is possible is to define the post-blit function to work on the already-blitted destination object. For example, if you don't want the source and the destination share a member slice, the destination object's post-blit can make a copy. > Regards > Ritu Ali P.S. There is also the D.learn newsgroup where such threads are enjoyed even more. :) |
December 29, 2013 Re: Bypassing the postblit? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli |
> No. In D, struct are freely copied or moved depending on whether the source is an lvalue or an rvalue. What is possible is to define the post-blit function to work on the already-blitted destination object.
>
> For example, if you don't want the source and the destination share a member slice, the destination object's post-blit can make a copy.
Ok, I will give you some background of what I am trying to do.
I have a struct that wraps a class object and lazily initializes it. Now in case the struct instance is passed as an argument to a function and it has not been initialized yet, the default copy constructor and the postblit do not offer a possibility to initialize the class object before copying.
Any possibility of *preblit* kind functionality?
Regards
- Ritu
|
December 29, 2013 Re: Bypassing the postblit? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ritu | Am 29.12.2013 17:22, schrieb Ritu:
>
>> No. In D, struct are freely copied or moved depending on whether the
>> source is an lvalue or an rvalue. What is possible is to define the
>> post-blit function to work on the already-blitted destination object.
>>
>> For example, if you don't want the source and the destination share a
>> member slice, the destination object's post-blit can make a copy.
>
> Ok, I will give you some background of what I am trying to do.
>
> I have a struct that wraps a class object and lazily initializes it. Now
> in case the struct instance is passed as an argument to a function and
> it has not been initialized yet, the default copy constructor and the
> postblit do not offer a possibility to initialize the class object
> before copying.
>
> Any possibility of *preblit* kind functionality?
>
> Regards
> - Ritu
No unfortunately not. You could solve the issue by adding another level of indirection. So always allocate the additional indirection, then its save to copy it, and then you can lazy instaniate the actual instance when needed and all copies of your wrapper will see the instance.
Kind Regards
Benjamin Thaut
|
December 29, 2013 Re: Bypassing the postblit? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ritu | On Sunday, 29 December 2013 at 16:22:04 UTC, Ritu wrote:
> I have a struct that wraps a class object and lazily initializes it. Now in case the struct instance is passed as an argument to a function and it has not been initialized yet, the default copy constructor and the postblit do not offer a possibility to initialize the class object before copying.
Why this is a problem? You can create function which return class field from struct wrapper and make such function alias this, in addition postblit should allocate new class. The fact that original struct may have null value is irrelevant if copying is made correctly.
|
December 29, 2013 Re: Bypassing the postblit? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxim Fomin | On Sunday, 29 December 2013 at 18:40:07 UTC, Maxim Fomin wrote:
> On Sunday, 29 December 2013 at 16:22:04 UTC, Ritu wrote:
>> I have a struct that wraps a class object and lazily initializes it. Now in case the struct instance is passed as an argument to a function and it has not been initialized yet, the default copy constructor and the postblit do not offer a possibility to initialize the class object before copying.
>
> Why this is a problem? You can create function which return class field from struct wrapper and make such function alias this, in addition postblit should allocate new class. The fact that original struct may have null value is irrelevant if copying is made correctly.
It's a problem for "reference semantic structs" that need to be initialized. This is actually a "well know" and often encountered problem.
It strikes things like Appende, Array, and also built in AA's.
void foo(Appender!(int[]) app)
{
app.put(1);
}
void main()
{
Appender!(int[]) app1;
Appender!(int[]) app2 = appender!(int[]);
foo(app1);
foo(app2);
assert(app1.data == [1]); //Fails
assert(app2.data == [1]); //Passes
}
|
December 29, 2013 Re: Bypassing the postblit? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Benjamin Thaut | On Sunday, 29 December 2013 at 18:27:16 UTC, Benjamin Thaut wrote: > No unfortunately not. You could solve the issue by adding another level of indirection. So always allocate the additional indirection, then its save to copy it, and then you can lazy instaniate the actual instance when needed and all copies of your wrapper will see the instance. > > Kind Regards > Benjamin Thaut Even with that, you'd still have to make sure the newly inserted indirection gets initialized *prior* to the copy, so it's back to square one... > Am 29.12.2013 17:22, schrieb Ritu: >> Ok, I will give you some background of what I am trying to do. >> >> I have a struct that wraps a class object and lazily initializes it. Now >> in case the struct instance is passed as an argument to a function and >> it has not been initialized yet, the default copy constructor and the >> postblit do not offer a possibility to initialize the class object >> before copying. >> >> Any possibility of *preblit* kind functionality? >> >> Regards >> - Ritu Nope. What you are asking for is basically a default constructor, which D does not provide. Workarounds include the "static opCall" pattern, as well as the "function builder" pattern (eg: "MyStruct myStruct(Args args)") |
December 29, 2013 Re: Bypassing the postblit? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | Am 29.12.2013 20:26, schrieb monarch_dodra:
>
> Even with that, you'd still have to make sure the newly inserted
> indirection gets initialized *prior* to the copy, so it's back to square
> one...
>
For that you can easily disable the default constructor. And then make the user call a constructor of your choosing that way. I thought the entire point of this preblit was that both the original and the copy point to the same instance, when the instance is actually requested.
Kind Regards
Benjamin Thaut
|
Copyright © 1999-2021 by the D Language Foundation