Boost logo

Boost :

Subject: Re: [boost] [Test] should we consider to turn off argument deduction for 2nd template parameter
From: Gennadiy Rozental (rogeeff_at_[hidden])
Date: 2008-12-19 02:06:26


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

Regards,

Gennadiy


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