
On Jul 20, 2008, at 1:46 AM, Sean Parent wrote:
I think there are two separate notions being discussed here -
First is the notion of a partial function - assignment and copy are both partial functions and have a precondition that the rvalue be in a valid state.
This is the case that Dave brought up. I think it shouldn't be the main concern because: (1) non-PODs are generally always in a valid state when created and (2) it's already illegal to use a not-(fully-) initialized (POD) object as an r-value. My main concern was what happens when a type's designer divides that type's set of valid states into multiple "runtime types" (as you say below), but the user wants to be more flexible with cross- compatibility than the designer.
The second is the notion of a runtime type where once the type is determined it is fixed and assignment becomes defined only on items of the same type. I tend to shy away from implementing such types and usually prefer to document that assignment won't throw (perhaps unless some subtype throws) if the two objects are of the same runtime type (or have the same topology - or whatever a correct term would be for the circumstance).
The problem comes from regular (copy-)assignment being considered a special function. Library code makes assumptions that don't work if assignments aren't free-for-all. User code that wraps runtime types have to either add an invariant that all uses of that type are of the same assignment-compatibility class or do appropriate reconfigurations (or give up with an assertion or exception) when two objects of different a.c. classes clash.
There are cases where I think the notion of a runtime type is valid even when it makes assignment more partial than it would be otherwise - being partial doesn't effect the concept at all - but such a design choice should be weighed carefully.
Yes. I think an important thing to do for such types is to make sure that swap stays never-fail, like destructors and deallocators, by making sure it works even when the two objects are of different a.c. classes. That way: my_class & fake_assign( my_class &dest, my_class const &sour ) { my_class copy( sour ); copy.swap( dest ); // even if either "copy=dest" or "dest=copy" would fail return dest; } anyone who needs to assign across a.c. classes can work-around it and still have the option of the strong guarantee. -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com