[xsd-users] C++11, value semantics, and polymorphism

Boris Kolpackov boris at codesynthesis.com
Thu Feb 14 10:32:58 EST 2013


Hi Ray,

Ray Lischner <rlischner at proteuseng.com> writes:

> We are jumping head first into C++11 and very much want to take full
> advantage of value semantics. We want to be able to construct most Code
> Synthesis objects without resorting to any dynamic memory allocation.
> Unless there are plans for Code Synthesis 4 to support this functionality,
> we will undertake the work ourselves.

Yes, we do plan C++11 support, including move support, for the next release.
While it would be great to have someone give this a try before the final
release, the bad news is that I will only have something to try probably
around end-June. Until then my schedule is very tight.


> It is a straightforward matter to modify xsd::cxx::tree::one<>, 
> optional<>, and sequence<> to support value semantics as long as 
> the types are not polymorphic.

Right, we will have to have two different version of these. In fact,
we already do, for fundamental and user-defined types. In C++11 mode
we will just use the by-value version for all non-polymorphic types.


> But we need to support polymorphism, too. That's where we run into a
> hitch. I want the parsing functions to return values for value classes,
> but they must return pointers for polymorphic classes. I certainly 
> don't want to force the user of a class to write different code
> depending on whether it is polymorphic,

I don't think this would be forcing anybody. Down the line, polymorphic
and non-polymorphic roots will be handled in a very different ways. With
polymorphic, there will probably be a dynamic_cast to discover the
actual type (try supporting this with your pimpl approach).

Generally, polymorphism and by-value are in conceptual contradiction.
By-value assumes the size of the object is known and fixed (so stack
can be allocated for it). Polymorphism assumes we don't even know
which object it is, let alone its size. By-value is: here is a chunk
of memory, construct object foo there. Polymorphism is: this chunk of
memory contains some object that is-a foo. Using dynamic memory to
return a polymorphic object is the "C++ way" (think of the virtual
destructor mechanism -- it was augmented to call the correct operator
delete). Well, that was a bit of philosophical aside ;-).

Now, in ODB, for example, we have two versions of the database::load()
function. One which returns a (dynamically-allocated) object and one
that can load the state into an existing instance:

person p;
db.load (p, "John Doe");

This works well for when you want to avoid allocations. We could do
this with parsing function, but I am not even sure it makes sense:
How will you know which object is being parsed? The only way to do
this generally is to examine the element name (or xsi:type). But
then, seeing that you already have the DOM element, you can just
call the parsing constructor directly and place the object anywhere
you want.

I guess this could still be useful for situations like "the response
to this message can only be class foo".


> so the only solution I see is for xsd to generate a pimpl wrapper
> for polymorphic classes to hide the difference.

There are so many issues/complications with this approach that I don't
even know where to begin (inheritance, type discovery, code bloat,
customizability, etc, etc). I don't think we will go this route.


> "is there any other way to support value semantics and polymorphism?"

I think we should just keep it simple and return values by-value and
use pointers/dynamic memory for polymorphic objects. Parsing functions
will return std::unique_ptr for polymorphic roots.

Boris



More information about the xsd-users mailing list