|
Boost : |
From: David Abrahams (abrahams_at_[hidden])
Date: 2001-05-03 08:04:07
I am in Copenhagen at the C++ committee meeting, and as such have only time
for very brief comments.
As Alexey is one of the principal contributors to this library with proven
good judgement I give his remarks extra weight out-of-hand. His remarks
should be given (nearly) as much weight as mine (I am the maintainer).
Beside that, I agree with most of what Alexey has written on its own merits.
The proposed changes to this library need to be stabilized quickly if they
are to be considered. That means controversial changes should be removed at
least temporarily so that the vast majority of the work, which is excellent,
can be saved.
Regards,
Dave
----- Original Message -----
From: "Daryle Walker" <darylew_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Wednesday, May 02, 2001 9:40 AM
Subject: [boost] Re: About "dlw_oprs.zip" version 25
> on 4/30/01 2:42 AM, Aleksey Gurtovoy at alexy_at_[hidden] wrote:
>
> > Daryle Walker wrote:
> >> Version 25 of "dlw_oprs.zip" has a new trial name for the unary
operator+()
> >> helper class template. It has adaptations for the newest Boost
release, and
> >> some general improvements.
> >
> > IMO the new unary operator+() name - 'identity_querible' - is still
> > counter-intuitive. I would suggest to go with Dave's version -
> > 'unary_plusable'; it's much more easy to remember, and, as Dave said,
> > accurate and consistent with the documented naming strategy; to my ears
it's
> > not even ugly :).
>
> That name doesn't match the other names that well. For instance, the
> template for the binary + is called "addable," not "binary_plusable." The
> template is named after the operation, not the operator. The operation
that
> the unary + does has a name, the identity function. That's where I get
the
> name from. The major exceptions are "left_shiftable" and
"right_shiftable,"
> since their operations have no other name (that I know of).
>
> > Some other random comments:
> >
> > 1) I am against including the 'unsigned_integer_convertible',
> > 'signed_integer_convertible', 'float_convertible' and their composite
> > operator classes into the library. First at all, I find it unnatural,
> > unnecessary and unsafe for a class to define an implicit conversion
> > operators in the way 'signed_integer_convertible' class template (for
> > example) does it:
> >
> > operator signed char() const {
> > return static_cast< ::boost::intmax_t >( static_cast<const T&>(*this) );
> > }
> > operator short() const {
> > return static_cast< ::boost::intmax_t >( static_cast<const T&>(*this) );
> > }
> > operator int() const {
> > return static_cast< ::boost::intmax_t >( static_cast<const T&>(*this) );
> > }
> > // etc.
> >
> > It's unnatural, because defining an implicit type conversion operator
for
> > the class is a statement of the close relationship between two types,
and,
> > at least for me, it's confusing and it "washes out" the semantics of the
> > class, when there are too many types/classes for which such statement
was
> > made.
>
> I want to be able to simulate the "unreasonable" conversions C++ allows
> between all the arithmetic types.
>
> > Taking the 'bitint<>' class template as an example ('bitint.zip' archive
in
> > the vault; as far as I understand, it was the main motivation for
proposing
> > the discussed templates into the library), when I write 'bitint<32>' I
would
> > expect the class to define only _one_ implicit conversion operator - on
my
> > platform, it would be 'operator int() const'. Also, I find it
_technically_
> > wrong that with current version of the class I will also get "for free"
> > implicit conversion operators to 'short', 'char' etc. and can write
> > something like
> >
> > char c = bitint<32>(100000);
> >
> > without getting a single warning from the compiler about data loss in my
> > code (also, see below).
> >
> > It's also unnatural because it requires the target class to define a
> > conversion to the "biggest" signed or unsigned type instead of
conversion to
> > the most suitable one (that in some cases can also lead to a performance
> > degradation).
>
> Some types may not be able to determine which integral type is the most
> suitable, so choosing the largest is the safest option.
>
> > It's unnecessary, because providing just one conversion operator, e.g.
> > 'operator int() const':
> >
> > struct my { operator int() const { return 0; } };
> >
> > is enough for the following statements to compile successfully (except
> > warnings, see below):
> >
> > char c = my(); // 1
> > short s = my(); // 2
> > int i = my();
> > long l = my();
> >
> > It's unsafe, because the discussed templates move a dangerous code from
a
> > client side to the library header, thus making it look less
suspicious/more
> > easy to accept and, on some compilers, just turning off the diagnostics.
> > Taking the above code as an example, a good compiler will issue a
warning
> > for the lines 1 and 2 about implicit arithmetic conversions from 'int'
to
> > 'short' and 'char' that can lead to a data loss, which is IMO a good
thing.
> > But if, instead of providing a single conversion operator to the most
> > appropriate type, you decide to use 'signed_integer_convertible' class,
> >
> > struct my : signed_integer_convertible<my>
> > { operator long() const { return 0; } };
> >
> > the warnings will be issued for the code in the library's header, or not
> > issued at all (!) (also often you don't even have a chance to find out
which
> > lines in your code caused these warnings). The latter is a problem of
those
> > particular compilers, of course, but the main point remains - hiding
> > implicit conversions, that can lead to a data loss, in the header is not
a
> > thing that a good library should do.
>
> I changed the operator templates to add an explicit conversion to their
> final type, avoiding those warnings.
>
> > 2) All words in the "Use of _Concepts_" section's title are
capitalized,
> > despite that the very first sentence of the section says:
> > "The discussed concepts are not necessarily the standard library's
concepts
> > (CopyConstructible, etc.), although some of them could be; they are what
we
> > call concepts with a small 'c'." :). I think the title should be "Use of
> > _concepts_".
>
> OK.
>
> > 3) I remember that the name 'totally_comparable' was born as a
compromise
> > between my suggestion of plain 'comparable' (with which Dave was
> > disagreeing) and the previous 'totally_ordered', but looking at it now,
I
> > think that the compromise is worse that both of the alternatives.
> > Personally, I am still favor 'comparable', and we already have 'bitwise'
and
> > 'shiftable' as precedents :), but I can live with 'totaly_ordered' too.
> > Dave?
>
> I changed it back to "totally_ordered." In fact, it inspired me to add
two
> new operator helper class templates. The "partially_ordered" template
> composes operator>, operator<=, and operator>= from _both_ < and ==, since
> this is the safe way to compose the others if the target type doesn't have
a
> total ordering. (It can also work for types with a total ordering, by
> "less_than_comparable" would be more efficient.) The "equivalent"
template
> composes operator== from < (x == y -> !(x < y) && !(y < x)).
>
> > That's all for now. Besides the commented issues, I think the library
looks
> > really good and I am looking forward to see it updated!
>
> --
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com
>
>
> To unsubscribe, send email to: <mailto:boost-unsubscribe_at_[hidden]>
>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk