Boost logo

Boost :

Subject: Re: [boost] [chrono] [dependence of common_type on Boost.TypeOf]
From: Jeffrey Lee Hellrung, Jr. (jhellrung_at_[hidden])
Date: 2010-08-14 04:16:12

On 8/13/2010 10:47 AM, vicente.botet wrote:
> ----- Original Message -----
> From: "Jeffrey Lee Hellrung, Jr."<jhellrung_at_[hidden]>
> To:<boost_at_[hidden]>
> Sent: Friday, August 13, 2010 7:28 PM
> Subject: Re: [boost] �
> My question is, if you can enumerate all possible candidates for (b ? t
> : u ) in terms of simple (C++03) transformations on T and U, then
> there's no need for Boost.TypeOf. You can get by with the "sizeof()
> trick", a la a slightly more elaborate boost::is_convertible. This
> could make the implementation more complex, but more robust (for C++03),
> which I think is an overall win. Do you agree?
> _______________________________________________
> I'm not an expert either and I don't see how we can get it without typeof. Anyway, how the possible implementation could be more robust?

[Changed subject to be more accurate.]

Perhaps robust wasn't the right word. More general? Essentially, I
think it's "better" if common_type doesn't rely on Boost.TypeOf, as then
it will work regardless of type registration in C++03. I don't know if
this is a relevant concern at this point in time, though. Don't most
C++ compilers in wide use support an efficient implementation of
BOOST_TYPEOF or decltype?

As for an implementation independent of Boost.TypeOf, this might be
relevant, although not necessarily definitive:

I'm not sure what is meant by "pointer conversions" and "reference
conversions", but I'd guess it just unions cv qualifiers and chooses the
better conversion to one pointer/reference type or the other. E.g.,
choose the better conversion between (b ? t : u) to T {maybe-cv} & and U
{maybe-cv} &, where t is of type T& and u is of type U&.

I think a Boost.TypeOf-less implementation of common_type is possible
because I don't think the compiler can manufacture some mysterious "3rd
type" out of thin air from the types of the lhs and rhs expressions of
the conditional operator. In other words, given

struct X0;
struct X1;
struct X2;

bool cond();
X0 x0();
X1 x1();

then (cond() ? x0() : x1()) can't possibly be anything related to X2, no
matter how X0, X1, and X2 are defined. Is that accurate? If so, it
must be that (cond() ? x0() : x1()) must have type X0 or X1.
Determining which of those 2 choices it is can be deduced using the
"sizeof trick":

typedef char (&y0)[1];
typedef char (&y1)[2];
y0 deduce(X0);
y1 deduce(X1);

static const bool is_x0 = sizeof( deduce(cond() ? x0() : x1()) ) ==
sizeof( y0 );

Obviously, some care needs to be taken when these definitions of deduce
produce ambiguous overloads, but hopefully I've better conveyed the idea.

And if this whole endeavor sounds completely unnecessary, feel free to
say so, and I'll drop the discussion ;)

- Jeff

Boost list run by bdawes at, gregod at, cpdaniel at, john at