Archived
This forum has been archived. Please start a new discussion on GitHub.
C++ mapping: availability of constructor with field parameters for structs
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
-
Hi,
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:// Slice struct S { string name; int count; }; // C++ S s = { "joe", 5 };
We'll clear this up in the next release.
Regards,
Mark0 -
Hi 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.return RGBColor(255,0,0); // won't work // must instead be written as RGBColor red = {255,0,0}; return red;
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.
- Sidney0 -
Hi,
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,
Mark0 -
Hi Mark,The goal of the C++ mapping for structures was to preserve their status as a POD type.
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:RGBColor(const Ice::Byte & _r, const Ice::Byte & _g, Ice::Byte & _b) : r(_r), g(_g), b(_b) {}
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.If we added a one-shot constructor, we would not only remove this quality but also potentially break backward compatibility with existing applications.0 -
Hi,
As stated on the Wikipedia page, POD types cannot have user-defined constructors.you already define parameterless default constructors
Regards,
Mark0 -
Hi 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, Sidney0 -
Umm.. what about using this compiler directives for your structures:
["cpp:class"] struct MyStruct { };0 -
chow: this would have significant impact on the code.
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.0 -
Hi Sidney,
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,
Bernard0 -
I stand corrected, a little bit of confusion on my side... Thanks.
Sidney0