C++ mapping: availability of constructor with field parameters for structs

in Help Center
Hi all,
Section 6.7.2 of the Ice User Manual states the following:
Structures also have a second constructor that has one parameter for each data member. This allows you to construct and initialize a class instance in a single statement (instead of first having to construct the instance and then assigning to its members).
However, if I use the standard 'struct as struct' C++ mapping, this second constructor appears not to be generated in Ice 3.4.0.
I am really in need of this functionality. Is this a bug or will the second constructor only be generated in "[cpp:class]" mode by design?
Regards, Sidney
Section 6.7.2 of the Ice User Manual states the following:
Structures also have a second constructor that has one parameter for each data member. This allows you to construct and initialize a class instance in a single statement (instead of first having to construct the instance and then assigning to its members).
However, if I use the standard 'struct as struct' C++ mapping, this second constructor appears not to be generated in Ice 3.4.0.
I am really in need of this functionality. Is this a bug or will the second constructor only be generated in "[cpp:class]" mode by design?
Regards, Sidney
0
Comments
That's a bug in the documentation. The C++ mapping for non-class structures has never generated a "one-shot" constructor because you can use aggregate initialization in this case. For example: We'll clear this up in the next release.
Regards,
Mark
There's some things one can do with a "real" constructor that one cannot do with an aggregate initialization - the aggregate initialization is only usable when declaring a named variable, thereby preventing use of the struct as a "rhs-value". This prevents real-life uses, eg.
In the RGBColor example, this isn't too bad, but if you have deeply nested structs, this solution becomes problematic. In that case, it is hard to see what's going on without the typename information provided by a true constructor call.
In short, I would argue in favor of generating proper constructor boilerplate code also for structs in the C++ mapping. I hope you are willing to consider this.
- Sidney
The goal of the C++ mapping for structures was to preserve their status as a POD type. If we added a one-shot constructor, we would not only remove this quality but also potentially break backward compatibility with existing applications. I think the only way it would be feasible would be with the use of a new metadata tag.
Regards,
Mark
Yes, that is a desirable property and I fully agree that you shouldn't do anything to break that.
Just to make sure we're talking about the same thing, Id' basically like to have something like this, perhaps defined inline (inside the class declaration) to ensure zero overhead:
I don't see how adding such a constructor, that takes values for all member fields, would break the "PODness", so to speak. A user would in no way be obliged to use the "initialize-all-fields-by-parameter" constructor; and you already define parameterless default constructors.
As stated above, I don't think you would take anything away from the POD-ness of the struct (everything that worked before will still work). And after a bit of thinking I cannot come up with any case that could lead to breaking backward compatibility, myself, so I'm curious about things that could go wrong there.
As stated on the Wikipedia page, POD types cannot have user-defined constructors. We only define a default constructor for a non-class structure when at least one of its members declares a default value. The constructor is unavoidable in this case, and losing the POD-ness of the type is the price you pay for the convenience of the default values. There would be no harm in adding a one-shot constructor in this case, and we'll probably do that in the next release.
Regards,
Mark
You are right, I overlooked the union case -- nasty.
If you add the one-shot constructor in case you make a default constructor anyway (in case of default values), that would be pretty useful I think.
Best regards, Sidney
["cpp:class"] struct MyStruct { };
As far as I can tell, exchanging classes over an interface implies implementation and registering of a factory, incurs a slight performance penalty, and implies that the classes are to be used via Ice's shared pointer mechanism.
While this may or may not be a good idea in it self, it differs significantly from the way structs are supported by the C++ runtime. All I need, really, is all-member constructors for the structs.
The "[cpp:class]" metadata suggested Brian, and that you mentioned in your first post, is not the same as replacing your Slice 'struct' by a Slice 'class'. In particular, there would be no factory generated or implemented/registered by you.
With "[cpp:class"], you'd get Ptrs and ref-counted objects, instead of structs passed by value/reference. And this was indeed the motivation for adding this metadata: handling structs as Ptrs is more efficient in some situations.
Best regards,
Bernard
Sidney