|
Boost : |
Subject: Re: [boost] [Test] should we consider to turn off argument deduction for 2nd template parameter
From: Paul A. Bristow (pbristow_at_[hidden])
Date: 2008-12-19 07:03:05
> -----Original Message-----
> From: boost-bounces_at_[hidden] [mailto:boost-bounces_at_[hidden]]
On
> Behalf Of Gennadiy Rozental
> Sent: 19 December 2008 07:06
> To: boost_at_[hidden]
> Subject: Re: [boost] [Test] should we consider to turn off argument
deduction for 2nd
> template parameter
>
> Thorsten Ottosen <thorsten.ottosen <at> dezide.com> writes:
>
> >
> > Hi Genndiy,
> >
> > When I write code like
> >
> > BOOST_CHECK_CLOSE( a->conditionals().sum(), 2., 0.001f );
> >
> > I tend to get a compilation error the first time, because I wrote
> >
> > BOOST_CHECK_CLOSE( a->conditionals().sum(), 2, 0.001f );
> >
> > I think that many users are not helped very much by the resulting error
> > messages deep inside the test library.
> >
> > Maybe we should consider to turn off deduction for the second argument
with
> >
> > template< class T >
> > bool operator()( T l, mpl::identity<T>::type r, ... );
> >
> > ?
> >
> > Any thoughts.
>
> Hi, Thorsten
>
> I does seem unfortunate that we can't figure out conversion on a fly. You
> solution have couple problems though. For once it's asymmetrical, which
means it
> only helps with second parameter, and not the first. And second, what even
worse
> it would lead to incorrect result in a case if first parameter is integral
type
> and second is floating point.
>
> floating_point_promotion is not what we need here as well: we don't need
to
> promote float to double.
>
> What we really need is to figure out "super" type out of two supplied and
try to
> convert both arguments to it. numeric::conversion_traits<T1,T2>::supertype
fits
> perfectly here.
>
> Here how the code looks like:
>
> struct BOOST_TEST_DECL check_is_close_t {
> // Public typedefs
> typedef bool result_type;
>
> template<typename FPT1, typename FPT2, typename ToleranceBaseType>
> bool
> operator()( FPT1 left, FPT2 right,
percent_tolerance_t<ToleranceBaseType>
> tolerance,
> floating_point_comparison_type fpc_type = FPC_STRONG )
> {
> typedef typename numeric::conversion_traits<FPT1,FPT2>::supertype
FPT;
>
> close_at_tolerance<FPT> pred( tolerance, fpc_type );
>
> return pred( left, right );
> }
> template<typename FPT1, typename FPT2, typename ToleranceBaseType>
> bool
> operator()( FPT1 left, FPT2 right,
fraction_tolerance_t<ToleranceBaseType>
> tolerance,
> floating_point_comparison_type fpc_type = FPC_STRONG )
> {
> typedef typename numeric::conversion_traits<FPT1,FPT2>::supertype
FPT;
>
> close_at_tolerance<FPT> pred( tolerance, fpc_type );
>
> return pred( left, right );
> }
> };
>
> The changes are small and the only downside it new dependency on numeric
> conversion headers. But I find it worth the price. One more thing we may
do on
> top of this is to validate against both FTP1 and FTP2 type to be integral:
we
> don't really want to check closeness of integer values.
>
> What do you think?
>
> Unless someone objects, I'll check this in tomorrow
Looks good to me - but obscure enough to merit a comment in the code too?
Paul
--- Paul A. Bristow Prizet Farmhouse Kendal, UK LA8 8AB +44 1539 561830, mobile +44 7714330204 pbristow_at_[hidden]
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk