Opened 12 years ago
Closed 12 years ago
#4530 closed Bugs (fixed)
errors with is_convertible on msvc10
Reported by: | Christopher Schmidt | Owned by: | John Maddock |
---|---|---|---|
Milestone: | Boost 1.44.0 | Component: | type_traits |
Version: | Boost Development Trunk | Severity: | Problem |
Keywords: | Cc: |
Description
#include <boost/spirit/include/qi.hpp> #include <boost/utility/enable_if.hpp> #include <boost/type_traits/is_convertible.hpp> #include <type_traits> template<typename T> struct test { template<typename A> test(A&&, typename boost::enable_if<boost::is_convertible<A&&, T> >::type* =0); }; int main() { typedef boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard,true,false> A; boost::is_convertible<test<A>, A>::value; //std::tr1::is_convertible<test<A>, A>::value; }
This snippet fails on msvc10 with the following errors:
1>z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(295): error C2039: 'value' : is not a member of 'boost::detail::is_convertible_basic_impl<From,To>' 1> with 1> [ 1> From=test<A> , 1> To=A 1> ] 1> z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(372) : see reference to class template instantiation 'boost::detail::is_convertible_impl<From,To>' being compiled 1> with 1> [ 1> From=test<A> , 1> To=A 1> ] 1> z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(418) : see reference to class template instantiation 'boost::detail::is_convertible_impl_dispatch<From,To>' being compiled 1> with 1> [ 1> From=test<A> , 1> To=A 1> ] 1> z:\dev\projekte\boost\boost-dev\boost\boost\utility\enable_if.hpp(36) : see reference to class template instantiation 'boost::is_convertible<From,To>' being compiled 1> with 1> [ 1> From=test<A> &, 1> To=A 1> ] 1> z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(263) : see reference to class template instantiation 'boost::enable_if<Cond,T>' being compiled 1> with 1> [ 1> Cond=boost::is_convertible<test<A> &,A>, 1> T=void 1> ] 1> z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(295) : see reference to class template instantiation 'boost::detail::is_convertible_basic_impl<From,To>' being compiled 1> with 1> [ 1> From=test<A> , 1> To=A 1> ] 1> z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(372) : see reference to class template instantiation 'boost::detail::is_convertible_impl<From,To>' being compiled 1> with 1> [ 1> From=test<A>, 1> To=A 1> ] 1> z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(418) : see reference to class template instantiation 'boost::detail::is_convertible_impl_dispatch<From,To>' being compiled 1> with 1> [ 1> From=test<A>, 1> To=A 1> ] 1> z:\dev\projekte\_test\main.cpp(17) : see reference to class template instantiation 'boost::is_convertible<From,To>' being compiled 1> with 1> [ 1> From=test<A>, 1> To=A 1> ] 1>z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(295): error C2065: 'value' : undeclared identifier 1>z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(295): error C2955: 'boost::type_traits::ice_or' : use of class template requires template argument list 1> z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\detail\ice_or.hpp(21) : see declaration of 'boost::type_traits::ice_or' 1>z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(295): error C2057: expected constant expression 1>z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(418): error C2975: 'val' : invalid template argument for 'boost::integral_constant', expected compile-time constant expression 1> z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\integral_constant.hpp(18) : see declaration of 'val'
Switching to std::tr1::is_convertible makes the code compile fine.
Change History (2)
comment:1 by , 12 years ago
Status: | new → assigned |
---|
comment:2 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Note:
See TracTickets
for help on using tickets.
Hmmm... I think this is a compiler bug, in trying to work out if test<A> is convertible to A the compiler is for some reason trying to instantiate test<A>::test<A>(test<A>) which causes a cyclic dependency in is_convertible. GCC handles the same code just fine, and switching to std::tr1::is_convertible at the top level breaks the cyclic dependency.
I think I can fix this long term by switching over to using the _ _is_convertible compiler intrinsic - but this also means switching is_convertible over to C++0x behaviour from TR1 behaviour which will be a breaking change.... and I'm not sure C++0x behaviour can even be implemented in the language yet for compilers that don't have the intrinsic!
Will investigate some more.