----- Original Message ----- From: "Peter Dimov" <[EMAIL PROTECTED]> To: "Boost mailing list" <[EMAIL PROTECTED]> Sent: Thursday, December 12, 2002 1:00 PM Subject: Re: [boost] Formal review: Optional library
> From: "Fernando Cacciola" <[EMAIL PROTECTED]> > > > Yes, I thought about that, too. But if the current swap semantics are > > > retained, it should simply be removed. Otherwise optional<T>::swap must > > > offer at least swap(T&, T&)'s guarantee. > > > > > I'm not sure I follow. > > What are swap(T&, T&) guarantees in general? > > I thought this depended on the specific type. > > True, swap()'s guarantees depend on the type. If T provides a > nothrow/strong/basic swap, optional<T>::swap should be at least > nothrow/strong/basic, respectively. I think that this can be done provided > that T(T const &) is strong and T::~T is nothrow. > I still have to tink about this ... > > Anyway, as I posted recently, I'm just about to conclude that relational > > operators > > could be properly defined as a synonim for: get_pointer(o1) .relop. > > get_pointer(o2). > > I found this definition totally consistent with pointer semantics and the > > implied > > aliasings. > > Optional does not have pointer semantics. > Not _entirely_, sure; but I think it can be accurately said that it has _partly_ pointer semantics, which is reflected by its pointer-like interface, and _partly_ value semantics, which is reflected by its container-like interface. Precisely because its dual nature can be confusing, it is very important that boths parts of the interface, which reflect different semantics, can be unambiguously differentiated so the actual semantic can be inferred without doubts. In order to achieve this, I considered fundamental the following rule of thumb: If optional<> is replaced by a pointer, and provided that uninitialized optionals are defined as null pointers, any exression using optionals should either fail to compile or behave exactly the same. This rule allows the programmer to unambiguously infer the semantic of a given expression using optional. > Two optionals can never alias each > other. Unless they are both uninitialized or are actually the same. > "Consistent with pointer semantics" doesn't make sense. Why? The pointer-like interface associates a pointer value to an optional object. Having relop be defined to compare this pointer value makes just as much sense as having operator*() dereference this pointer, having operator-> return it, etc... >Optional is not a pointer. Don't try to make it into one; you'll arrive at shared_ptr. > ;-) > It is not completely a pointer, neither is not completely not a pointer. :-) In fact, shared_ptr<> can well be used to convey the same optionality of a value. This is important: in an optional-less world, pointers and smart-pointers are used to handle optional values. This makes a lot of sense and works pretty well in many situations. It is actually the choice of value _storage_ which decides whether to use optional<> or shared_ptr<>. If it makes sense to allocate the optional object dynamically, then using shared_ptr<> is a very good choice; but if the ubiquity of the type makes a dynamic allocation wastefull, go with optional<>. But from the reciever POV, it should be the same whether a builtin pointer, a smart pointer, or optional was used. This is why the poiner-like interface is important. The difference between using a pointer (smart or not) or using optional shall not be found on the operations that access the value, this is unnecesary. The difference shall be in the way the value is wrapped: optional<> uses value semantics for this part, which is what makes it usefull, since it saves you from a wastefull and protocolar dynamic allocation/deallocation; but that's is its fundamental purpose; for the rest, familliar smart-pointer semantics are appropiate. Thus, optional<> uses a pointer-like interface for everthing except those operations that deal with initializing, replacing and uninitializing the value. I know that (*o1==*o2) is undefined for uninitialized optionals, but this is equally undefined for pointers, so I don't see it as such a big problem. optional<> is not intended to replace _all_ situations were optional values are used. It is itended to be used on those situations were pointers are difficult to use; but I expect programmers to keep using pointers were appropriate. For example, as I said before, optional arguments to a function should not be coded with optional<> but with conventional pointers. Therefore, the shortcut which is gained by having (o1==o2) compare values, handling uninitialized cases, is in itself very useful, but gives optional<> a peculiarity which spoils its ubiquity. Fernando Cacciola _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost