Boost logo

Boost :

From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2008-06-03 11:45:52


On Mon, Jun 2, 2008 at 7:08 PM, Steven Watanabe <watanabesj_at_[hidden]> wrote:
> AMDG
>
> Sean Huang wrote:
>> The following code generates a compile error with VC8+SP1:
>>
>> **************************************************************************
>> #include <boost/lambda/lambda.hpp>
>> #if 1 // compiles when set to 0
>> # include <boost/utility/result_of.hpp>
>> # include <boost/range/functions.hpp>
>> #else
>> # include <boost/range/functions.hpp>
>> # include <boost/utility/result_of.hpp>
>> #endif
>>
>> #include <boost/function.hpp>
>> #include <boost/type_traits/is_same.hpp>
>>
>> typedef boost::function< int ( void ) > FuncType;
>>
>> BOOST_STATIC_ASSERT( ( boost::is_same< boost::result_of< FuncType ()
>>
>>> ::type, int >::value ) );
>>>
>
> I've traced the problem as far back as I can:
>
> #include <boost/mpl/has_xxx.hpp>
>
> namespace boost {
> namespace lambda {
> namespace detail {
>
> BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type);
>
> }
> }
> }
>
> namespace boost { namespace mpl { namespace aux {
> BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_apply, apply, false)
> }}}
>
> #include <boost/mpl/assert.hpp>
>
> struct with_result_type {
> typedef int result_type;
> };
>
> BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type);
>
> BOOST_MPL_ASSERT((has_result_type<with_result_type>));

Wow. Way to track down a really obscure bug! So, MPL's has_xxx is the culprit.

I played around with has_xxx quite a bit once, and I remember
template-based sfinae can be finicky between compilers. From what I
can tell in Steve's example, ::has_result_type,
::boost::mpl::aux::has_apply, ::boost::lambda::detail::has_result_type
all share the same substitute -
::boost::mpl::aux::msvc71_sfinae_helper. The problem appears to be
triggered by the order in which templates using this substitute are
specialized - definitely a bug in msvc.

Boost can work around the problem by using a different substitute
helper for each has_xxx. The attached patch shows one way to do this
and appears to fix the problem.

Daniel Walker




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