Boost logo

Boost :

Subject: Re: [boost] [chrono] [dependence of common_type on Boost.TypeOf]
From: Adam Merz (adammerz_at_[hidden])
Date: 2010-08-16 01:23:56


vicente.botet <vicente.botet <at> wanadoo.fr> writes:
> ----- Original Message -----
> From: "Adam Merz" <adammerz <at> hotmail.com>
> To: <boost <at> lists.boost.org>
> Sent: Sunday, August 15, 2010 9:44 AM
> Subject: Re: [boost][chrono] [dependence of common_type on Boost.TypeOf]
>
> >
> > vicente.botet <vicente.botet <at> wanadoo.fr> writes:
> >> Hi again,
> >> I have reached to manage with the ambiguous overloads and all the tests
> >> works as before.
> >> I have do it as follows:
> > <snip code>
> >
> > That doesn't seem very robust in the case that there is no common type (in
> > terms of the compiler error anyway).
>
> Could you send the compiler error so we can talk of concrete things?
>
> Thanks,
> Vicente

Really? You were just speaking of ambiguity errors yourself...

Okay then, two issues I see with a sizeof-based approach as you've shown it:
First, it requires that both types be default constructable; otherwise, you get
errors like the following (using MSVC10):

1>error C2512: 'Bar::Bar' : no appropriate default constructor available
1> see reference to class template instantiation 'common_type2<T1,T2>' being
1> compiled
1> with
1> [
1> T1=Foo,
1> T2=Bar
1> ]

This can of course be worked around by working in terms of pointers to the
provided types rather than the types themselves. Second, if there is no
common type, you get potentially confusing ambiguity errors:

1>error C2446: ':' : no conversion from 'Baz' to 'Foo'
1> No constructor could take the source type, or constructor overload
1> resolution was ambiguous
1> see reference to class template instantiation 'common_type2<T1,T2>' being
1> compiled
1> with
1> [
1> T1=Foo,
1> T2=Baz
1> ]
1>error C2070: ''unknown-type'': illegal sizeof operand

Or, if you make the aforementioned pointer changes, you get the even more
confusing:

1>error C2446: ':' : no conversion from 'Baz *' to 'Foo *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast,
1> C-style cast or function-style cast
1> see reference to class template instantiation 'common_type2<T1,T2>' being
1> compiled
1> with
1> [
1> T1=Foo,
1> T2=Baz
1> ]
1>error C2070: ''unknown-type'': illegal sizeof operand

The approach I've shown yields a more-familiar static assertion error (which
will of course vary in readability depending on your compiler's support for
C++0x's static_assert (I've changed the code I posted to use a nested struct
no_common_type rather than void for readability purposes):

1>error C2338: (!boost::is_same<type, no_common_type>::value)
1> see reference to class template instantiation 'common_type1<T1,T2>' being
1> compiled
1> with
1> [
1> T1=Foo,
1> T2=Baz
1> ]

Obviously, a named bool or BOOST_MPL_ASSERT_MSG could be used instead to
potentially improve readability further.


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