$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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