|
Boost : |
From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2002-11-29 02:09:24
David B. Held wrote:
> > Fortunately, once you know what's happening, the bug is easy to
> workaround:
> >
> > template< typename T > struct pointer_type
> > {
> > typedef typename T::pointer_type type;
> > };
> >
> > #if defined(BOOST_MPL_MSVC_ETI_BUG)
> > template<> struct pointer_type<int>
> > {
> > typedef int type;
> > };
> > #endif
>
> So my understanding is if ETI instantiates the template and
> mutates it to int, this hack will prevent the compiler from
> trying to extract the nested type, by returning a bogus int
> type. And then, when the template gets *properly*
> instantiated, it will use the non-specialized version?
Yep.
> > template <class Policy>
> > struct get_category
> > {
> > typedef typename Policy::policy_category type;
> > BOOST_MPL_AUX_LAMBDA_SUPPORT(1,get_category,(Policy))
> > };
>
> Ok, so I see that this looks just like the policies. Since
> it is an MPL metafunction that passes through lambda, it needs
> to have the AUX macro just like the policies?
Correct.
> > Since, naturally, '_' placeholder doesn't have a nested
> > 'policy_category' member, the above will be ill-formed as
> > written when compiled on a non-conforming compiler.
>
> Yes, I noticed that. Early instantiation sure is a pain to
> work around.
Actually, ETI is irrelevant, here - it's just that without template template
parameters, the only way to extract the metafunction arguments is an
intrusive introspection mechanism hidden behind BOOST_MPL_AUX_LAMBDA_SUPPORT
macro, and, in its turn, the only way for the library to access the
information provided by the mechanism (metafunction's arity and exact
template arguments) is to look inside the metafunction - thus instantiating
it, possibly with one or more placeholder arguments. In general, it doesn't
always lead to an error; obviously, instantiating something as simple as
template< typename T1, typename T2 > struct is_same
: bool_c<false>
{
};
template< typename T > struct is_same<T1,T2>
: bool_c<true>
{
};
with either T1 or T2 (or both) == mpl::arg<n> is totally harmless. And even
this metafunction is OK:
template< typename Iterator > struct deref
{
typedef typename Iterator::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,deref,(Iterator))
};
as the library makes sure that all placeholders actually _do_ have a nested
'type' typedef, specifically for this purpose (on non-conforming compilers
only, of course). What the library can't do, is to accommodate all possible
nested typenames. So if you are doing something like
template< typename Policy > struct get_category
{
typedef typename Policy::policy_category type;
};
it becomes you responsibility to handle the case when 'Policy' is a lambda
placeholder - again, only if you are using 'get_category' in lambda
expressions, and you are dealing with a deficient compiler.
>
> > [...]
> > template <class Policy>
> > struct get_category
> > : mpl::if_<
> > mpl::is_placeholder<Policy>
> > , mpl::identity<Policy>
> > , get_category_impl<Policy>
> > >::type
> > {
> > BOOST_MPL_AUX_LAMBDA_SUPPORT(1,get_category,(Policy))
> > };
>
> So this is like a meta-compile-time check to avoid early
> instantiation?
Not exactly, see the above.
> And again, because get_category is a
> metafunction going through lambda, we need the AUX macro.
Yep, this one is correct.
> > On an aside note, in general, unless you are very intimate
> > with particular compiler's idiosyncrasies, it much easier
> > to debug a complex template code on more or less conforming
> > compiler (Comeau, Intel C++, GCC 3.2) and then adopt it for
> > MSVC and Borland, than fight with the last two while
> > catching your own bugs.
>
> Well, my code worked just fine on bcc and gcc before I started
> hacking it to pieces for MSVC.
Hmm, I am not sure how it could work on Borland without lambda support and
special care for placeholder arguments in 'get_category' :).
> The troubles started when MSVC didn't like 80% of what I had written for
the other compilers!
Well, now you know how to fight it!
> Thanks a lot for your help!
You are welcome!
Aleksey
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk