Boost logo

Boost :

From: Fernando Cacciola (fernando_cacciola_at_[hidden])
Date: 2003-08-28 07:49:44


Ok, both Joel G. and David A. clearly showed that references
can dangle in so many ways that it makes no sense to limit an
interface in order to protect against that.

I'm way overprotective, I guess
(maybe it's because I'll be father for the first time
in a couple of months :-)

But this is C++, I know I like it not getting in the way of
my conscious decisions.

I guess we would never explicitely use optional<T&> since this
is pretty much the same as plain T*, so the most important use case
if when we have optional<U> and U might happen to be a T&.

For consistency, it is important to be able to state that
optional<U> is a container that might be empty, or may have
1 object of type U.

On the one hand, I don't think of references as objects,
yet OTOH, it is a fact that they are pretty much like
objects in plenty of cases.
For instance, if I have:

template<class U, class V> struct S { U u ; V v ; } s ;

what if U and/or V are references?
That it mean that s.u and/or s.v are not objects?

At least from the generic programming POV they are, that's clear.

I guess it would help if we formaly introduce the following
concept:

[1] Reference Object:
Pragmatically, instances of type T(cv)& do in fact exist,
so these instances should be categorized as objects.
Such an "object" of type T(cv)& occupies the same
storage and has the same representation and copy
semantics of an object of type T(cv)*.
The fundamental distinction between "objects"
of type T(cv)& and objects of type T(cv)* is
that they have different assignment semantics.
In particular, the expression
u=v were u:T& and v:T is equivalent to
*pu=v were pu:T*.

Using this concept we can say that:
optional<U> contains or not 1 object of type U.
If U is of reference type, then the corresponding
reference object is contained.
If U implies aliasing, such as if U is of reference type,
so does optional<U>.

Well, this pretty much convers it.
The only remaining issue is the optional<> interface:

Currenty, there is the following:

optional<T>::optional ( T const& ) ;
optional<T>::reset ( T const& ) ;

But If 'T' is allowed to be a reference, then these should have to be
changed to:

optional<T>::optional ( T ) ;
optional<T>::reset ( T ) ;

the question is, what should be the 'conceptual' signature
of these functions? (how should they be documented).

The same goes for operator*().

For non-reference types, it is: T& operator*();
but for reference types, is has to be: T operator*();

Anyway, this issues are the same for tuples, so whatever it was
done there it can be done with optional<>.

Fernando Cacciola


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk