Boost logo

Boost :

From: Fernando Cacciola (fernando_cacciola_at_[hidden])
Date: 2004-01-11 16:27:08


"David Abrahams" <dave_at_[hidden]> escribió en el mensaje
news:brpc1pzi.fsf_at_boost-consulting.com...
> "Fernando Cacciola" <fernando_cacciola_at_[hidden]> writes:
>
> > Hi,
> >
> > I'm fixing the compilation problems with VC7.1 for the recently accepted
> > Numeric Conversions Library and found the following:
> >
> > (1)
> > I erroneously used a construct of the follwing form:
> >
> > typedef typename boost::is_same<T,S>::type is_trivial ;
> >
> > typedef typename boost::mpl::if_<is_trivial,ABC,DEF>::type type ;
> >
> > The error is in the "::type" after is_same<>; mpl::if_ can take the
traits
> > as is, without the "::type"
>
> It can, but it's not an error to supply the ::type.
>
OK

> > However, that code did pass many of the other compilers, so that
"::type"
> > does exist in some cases.
>
> The type should always exist.
>
OK

> > Is this a bug in the VC7.1 version of "is_same"? That is, was it
intended to
> > have "::type"?
>
> Is it a bug in the compiler? We can't know until you post a
> reproducible test case.
>
Oh! it must be a bug in my head....
I swear it didn't compile and it was fixed when I removed the "::type",
but now I can't reproduce it!! I've put the "::type" back in
and it work.....
(maybe it was a "typename" missing)

So forget about this one :-)

> > (2)
> > VC7.1 doesn't like the implementation of "mpl::equal_to" when the
operands
> > are "mpl::integral_c" of ENUMERATION type.
> > The problem is certainly related to the fact that the value_type to
compare
> > is an enum.
> >
> > I wonder if this is a general problem and I shouldn't use enums, at
least
> > for some compilers.. does anyone know?
> >
> > Assuming that using enums is OK, so that "equal_to" has to be fixed
>
> We can't know until you post a reproducible test case ;-)
>
> > I change the code to use my own version of equal_to, as follows:
> >
> > template<class T1, T1 val1, class T2, T2 val2>
> >
> > struct equal_to_helper
> > {
> > BOOST_STATIC_CONSTANT(bool, value = ( val1 == val2 ) ) ;
> > } ;
> >
> > template< typename BOOST_MPL_AUX_VOID_SPEC_PARAM(T1)
> > , typename BOOST_MPL_AUX_VOID_SPEC_PARAM(T2)
> > >
> > struct equal_to
> > {
> > typedef typename T1::value_type T1_val_type ;
> > typedef typename T2::value_type T2_val_type ;
> > typedef equal_to_helper< T1_val_type
> > ,BOOST_MPL_AUX_VALUE_WKND(T1)::value
> > ,T2_val_type
> > ,BOOST_MPL_AUX_VALUE_WKND(T2)::value
> > > helper ;
> >
> > BOOST_STATIC_CONSTANT(bool, value =
> > BOOST_MPL_AUX_VALUE_WKND(helper)::value );
> >
> > #if !defined(__BORLANDC__)
> > typedef mpl::bool_<value> type;
> > #else
> > typedef mpl::bool_< BOOST_MPL_AUX_VALUE_WKND(helper)::value > type;
> > #endif
> >
> > };
> >
> > Should we use adopt this implementation in mpl itself? Will it break
with
> > some compiler?
>
> I don't think so. Integral constants shouldn't be required to have a
> value_type IMO.

OK. A "real" fix my be to specialize equal_to to take advantage of
"integral_c" which does include "value_type"

> Anyway, it's unclear to me why your implementation
> would solve any problems. Can you explain it?
>
Sure.
This code is a simplier reproduction of the relevant mpl stuff.
You'll see at the bottom that the default equal_to implementation doesn't
work when the integral constant is of enumeration type.
At least when the enum is wrapped as in "integral_c"
My implementation, called "another_equal_to" here, works, but it uses the
actual integral type. (that's _why_ it works I think)

enum E { x } ;

template<class T, T v>
struct integral_c
{
  typedef T value_type ;
  static const T value = v ;
};

template<bool v>
struct bool_
{
  static const bool value = v ;
};

template< class T1, class T2>
struct equal_to
{
  static const bool value = ( T1::value == T2::value );

  typedef bool_<value> type;
};

template<class T1, T1 val1, class T2, T2 val2>
struct equal_to_helper
{
  static const bool value = ( val1 == val2 ) ;
} ;

template< class T1, class T2>
struct another_equal_to
{
  static const bool value =
equal_to_helper<T1::value_type,T1::value,T2::value_type,T2::value>::value;

  typedef bool_<value> type;
};

int main( int, char * [])
{
  equal_to< integral_c<int,0>, integral_c<int,0> > i ;

  equal_to< integral_c<E,x>, integral_c<E,x> > e ; // error here!!!!!

  another_equal_to< integral_c<E,x>, integral_c<E,x> > ae ;

  return 0;
}

Fernando Cacciola
SciSoft


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