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.