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 _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost