Boost logo

Boost :

From: Augustus Saunders (infinite_8_monkey_at_[hidden])
Date: 2002-12-12 16:42:21


I think that a lot of this discussion is boiling down to whether or
not optional should sport a pointer interface at all. As previously
discussed, an optional cannot--doesn't want to--support several bits
of pointer semantics.

To me, the only really important benefit of pointer syntax is for
usage in generic code. While it is a convenient shorthand in regular
code, it is no more laborious, really, to type out some function
calls instead of operator* and operator&. So, if we set generic code
aside for a moment, I think that it is clear that a pointer interface
is dangerously misleading and should definitely be stricken.

However, I want to consider generic code again. Consdier iterators
and their (non)equivalence with pointers and how useful they are.
Concepts were invented to convey some requirements and guarantees for
generic code. This way, an interface that is a subset of a pointer's
interface can still be used when that is all that is needed. If we
want to be able to use optionals interchangeably with pointers, we
have to define some new concepts. Additionally, we need to define
some new traits to prevent optionals from being used in some contexts
that might otherwise compile. Then, in theory :), all the existing
generic boost code that can accept pointer like things needs to
re-evaluated to see whether or not the requirements can be loosened
to this new concept we make, and if not, to add some concept-checking
to make sure an optional isn't used.

Personally, I think that it is a good thing to define more refined
concepts. It helps us to think about our problems more clearly.
Right now, when writing generic code, we ask ourselves, do I really
need a RandomIterator, or will a ForwardIterator do? Then, since we
of course document such requirements :), it adds clarity to the code.
 So, here's my stab at defining some new concepts:

OptionalValue: meant to convey a value that is optional. Supports
operator bool, operator*, and operator&, where operator bool
indicates whether a value exists, operator* returns the value, and
operator& returns the address of the value. Note, specifically, that
optional values *may not be directly compared*. If you want to
determine whether two optionals are initialized with the same value,
you must spell it out:

if (o1 && o1 && *o1 == *o2)
{
  ...
}

Examples of OptionalValue: pointers, smart pointers, optional.

AliasedValue : specializes OptionalValue. An AliasedValue is an
OptionalValue with the additional operator==. The operator== of an
AliasedValue makes this guarantee:

av1 == av2 iff (av1 && av2 && &*av1 == &*av2) || (!av1 && !av2)

In other words, if two AliasedValues compare equal, then they are
aliases for the same value. Note, however, that poor taste in
operator overloading could satisfy the above expression without
complying.

Examples of AliasedValue: pointers, smart pointers

I haven't read through the standard concept definitions in a while,
so I may have strayed from the usual style for defining them,
although I think my idea is clear. Now, I can write generic code:

template <typename OptionalValue, typename Value>
bool is_equal_to_value( OptionalValue ov, Value v)
{
    if (ov)
       return *ov == v;
    else
       return false;
}

Once the language lawyers amoung us tighten down the scres on the
OptionalValue definition, then this code makes it perfectly clear
that pointers and optionals are completely interchangeable when
calling is_equal_to_value. It is also equally clear that you cannot
pass an optional to this function:

template <typename AliasedValue>
bool are_they_really_the_same_object(AliasedValue av1, AliasedValue
av2)
{
   return av1 == av2;
}

Now, if you want to leave a comparison operator in optional, that's
fine so long as we define some traights so that the above code can
concept check to make sure operator== is doing what it's supposed to.
 Then, code that was written specifically for optional (and
understands the different semantics) can still take advantage of the
convenience. However, if it was just me, I'd get rid of operator==
altogether if this pointer path is followed.

I can vote to accept if these concepts are defined to the group's
satisfaction, or if the pointer interface is removed. Like I said
before, I like the pointer interface, but I am not hung up on it.
But I feel stronly that we not introduce subtle new concepts with
giving them some authoritative definitions.

Cheers-
Augustus

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com


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