id,summary,reporter,owner,description,type,status,milestone,component,version,severity,resolution,keywords,cc 1916,[mpl] MPL_HAS_XXX_TRAIT_DEF bug in MSVC71,Adam Butcher ,Aleksey Gurtovoy,"The MSVC71 implementation of MPL_HAS_XXX_TRAIT_DEF does not correctly support defining a trait of the same name even if that is enclosed within a different namespace. It seems to have something to do with the instantiation of the 'msvc71_sfinae_helper'. In the code below I do the following: {{{ #!cpp namespace one { BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) BOOST_MPL_HAS_XXX_TRAIT_DEF(another_type) } namespace two { BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) } }}} Namespace two's {{{has_result_type}}} actually ends up testing for the presence of {{{another_type}}} rather than {{{result_type}}}. If the declarations in namespace one are reordered so that result_type trait is last, then the namespace two trait works as expected. I wrote a basic sfinae trait-check implementation myself which worked ok. Maybe something similar could be used for msvc71 in the mpl? If the following code is compiled with -DUSE_MPL_TRAIT_DEF then the mpl is used, otherwise my own implementation is used. {{{ #!cpp #if USE_MPL_TRAIT_DEF #define SELECTIVE_HAS_XXX_TRAIT_DEF BOOST_MPL_HAS_XXX_TRAIT_DEF #include #else #define SELECTIVE_HAS_XXX_TRAIT_DEF MY_HAS_XXX_TRAIT_DEF #define MY_HAS_XXX_TRAIT_DEF( trait ) \ template \ struct has_##trait \ { \ template \ static char test( U const volatile*, typename U::trait* = 0 ); \ static long test( ... ); \ \ static const bool value = sizeof test( static_cast(0) ) == sizeof(char); \ }; \ #endif namespace one { SELECTIVE_HAS_XXX_TRAIT_DEF(result_type) SELECTIVE_HAS_XXX_TRAIT_DEF(another_type) } namespace two { // This instantiation of msvc71_sfinae_helper in the msvc71 // implementation has been seen before --- but its function is that // of the last trait def. // // This line has the effect of defining a 'has_result_type' struct // that tests for 'another_type' in msvc71. // SELECTIVE_HAS_XXX_TRAIT_DEF(result_type) } template struct test; template <> struct test {}; struct X { typedef int result_type; typedef int another_type; }; struct Y { typedef int result_type; }; int main() { test< one::has_another_type< X >::value >(); test< one::has_result_type< X >::value >(); // this works but is actual testing for 'another_type'!!! test< two::has_result_type< X >::value >(); // this fails as it doesn't have 'another_type' test< two::has_result_type< Y >::value >(); } }}}",Bugs,new,Boost 1.36.0,mpl,Boost 1.35.0,Problem,,mpl MPL_HAS_XXX_TRAIT_DEF msvc,