Boost logo

Boost :

Subject: Re: [boost] review request: addition to type_traits library of is_less_comparable<T, U> and others
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2009-10-09 13:17:55


Frédéric Bron wrote:
>> Is it reasonable to additionally verify the returned type? IMO, such kind of
>> traits should not make assumptions about the operators meaning, they should
>> merely show whether the comparison expression is valid. Thus there also
>> should not be a fails-to-compile case.
>
> OK, what do you know if you know that you can write t<u but do not
> know if it is convertible to bool?
> You know that "t<u ;" is OK but maybe "if (t<u) ..." will not work ->
> compile time error.
> I think that in most cases you want to know that it behaves like
> operator< used with built-in types.

Knowing that an expression is valid and that the expression can be used
in a specific context are different things. Therefore I would like to
see the tools that provide these two kinds of knowledge decoupled.
Otherwise you make these traits bound to a single specific use case, no
matter how widely used it is.

> Maybe it could be interesting for some people to have an additionnal
> version just checking for existence but I am not convinced.
>
> I agree that it is not "nice" to have a compile time error when used
> with operator< returning void but I prefer that than returning true
> because this behaviour is not the one expected by operator<. If
> anybody has a solution on how to return false in such case...

You can achieve that with typeof/decltype. Something like that (not tested):

     #include <boost/type.hpp>

     namespace adl_block {

         struct something_else {};

         struct convertible_from_any
         {
             template< typename T >
             convertible_from_any(T const&);
         };

         something_else operator< (
             convertible_from_any, convertible_from_any);

         template< typename T, typename U >
         struct is_less_comparable_impl
         {
             typedef char yes_type;
             struct no_type { char _[2]; };

             template< typename V >
             static yes_type check(type< V > const&);
             static no_type check(type< something_else > const&);

             static T make_T();
             static U make_U();

             enum _
             {
                 value = sizeof(yes_type) ==
                 sizeof(check(type< decltype(make_T() < make_U()) >()))
             };
         };

     }

     template< typename T, typename U >
     struct is_less_comparable :
         mpl::bool_<
             adl_block::is_less_comparable_impl< T, U >::value
>
     {
     };


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