
On Mon, Jun 2, 2008 at 7:08 PM, Steven Watanabe <watanabesj@gmail.com> 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