|
Boost : |
From: David B. Held (dheld_at_[hidden])
Date: 2002-11-28 12:36:02
"Aleksey Gurtovoy" <agurtovoy_at_[hidden]> wrote in message
news:4034600A4760D411B8720001031D84FB01096569_at_postoffice.office.meta...
> [...]
> Actually, the errors have little to do with MPL in general or lambda in
> particular;
Andrei won't be happy to hear that. ;)
> [...]
> inside another class template definition, can choose, for its own internal
> purposes, to substitute 'storage_policy' by 'int' type - and proceed with
> further declarations.
Ouch! Who was the genius that implemented this?
> [...]
> 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?
> [...]
> Well, having said that, I should note that actually MPL's lambda on MSVC
> (and Borland, currently) _does_ work slightly differently from its normal
> counterpart, setting up some additional pitfalls.
Hey, that's not your fault. I'm just glad lambda can be *made* to work.
> [...]
> 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?
> [...]
> 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.
> [...]
> 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? And
again, because get_category is a metafunction going through lambda, we
need the AUX macro. I think it's sinking in, very slowly. ;)
> 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. The troubles started when MSVC didn't like 80% of
what I had written for the other compilers!
> [...]
> Attached is a modified 'smart_ptr.hpp' that more or less compiles on MSVC
> 6.5, Intel C++ 6.0, and GCC 3.2 (see the test for the details). You'll
need
> the latest boost CVS snapshot for that.
Dude, you rock!!! I haven't gotten a chance to play with the code yet, but
it
looks like you took care of most of my remaining problems. Thanks a lot for
your help!
Dave
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk